PowerShellでの資格情報の安全な扱い ── 平文パスワードをスクリプトから追放する

· · PowerShell, Windows, セキュリティ, 資格情報, DPAPI, 自動化, 運用改善, スクリプト

不具合調査やスクリプトのレビューでお客様のPowerShellスクリプトを拝見すると、かなりの確率で出会うものがあります。$password = "P@ssw0rd123"── ファイルサーバーへの接続、基幹システムのDB、メール送信、Web APIのキー。動かすことを優先した結果、パスワードが平文でスクリプトに埋め込まれたまま、共有フォルダやGitリポジトリで数年生き続けているのです。

厄介なのは、書いた本人も「良くないのは分かっている」ことです。では代わりにどうするのが正解なのかというと、SecureString、Export-Clixml、SecretManagement、資格情報マネージャー、Azure Key Vault…と選択肢が乱立していて、それぞれの守備範囲と限界が分かりにくい。しかも「SecureStringはもう推奨されない」という話まで聞こえてきて、何を信じればいいのか分からなくなる。この混乱には理由があり、整理すれば道筋は明確です。

この記事では、社内の運用スクリプトや定期バッチを管理する情シス・運用担当者を対象に、平文パスワードの何が問題かから始めて、PowerShellの資格情報の道具立てを仕組みごと整理し、「無人実行でどうするか」の現実解を判断表にまとめます。PowerShell 7.xを基準に、Windows PowerShell 5.1の現場への注意も併記します。

1. まず結論

  • 平文パスワードの問題は「ファイルが見えた時点で漏えい確定」になることです。Git履歴・共有フォルダ・バックアップ・ログと、スクリプトのコピーが増える経路すべてが漏えい経路になります。平文をSecureStringに変換するコード(ConvertTo-SecureString -AsPlainText)を書いても、元の平文がスクリプトやログに残るなら解決になりません。12
  • 対話的に使うスクリプトはGet-CredentialでPSCredentialを受け取るのが基本形です。パスワードは画面に表示されず、オブジェクトとして各コマンドの-Credentialパラメーターへ渡せます。3
  • SecureStringは「新規開発では推奨しない」と.NET公式が明記しています。暗号化はWindowsでのみ行われ、非Windowsでは内部が暗号化されません。一方PowerShellは互換性のためSecureStringを使い続けており、標準の受け渡し形式として当面は付き合うことになります。過信せず、自作の保護機構の土台にはしないでください。45
  • 無人実行での資格情報ファイル保存は、Export-ClixmlによるDPAPI暗号化が最小構成の実用解です。保存したユーザー・保存したマシンでしか復号できないため、ファイル単体が漏れても開けません。裏を返すと「タスクスケジューラの実行アカウント自身で保存する」必要があります。非Windowsでは暗号化されません。6
  • 複数の秘密を扱うならSecretManagement+SecretStoreで一元管理します。Set-Secret/Get-Secretの統一インターフェースで、ローカルのSecretStoreからAzure Key Vaultまで保存先を差し替えられます。ただし無人実行ではボールトパスワードの扱いが課題として残ります。78
  • 最優先の検討は「そもそも資格情報を持たない設計」です。実行アカウント(ドメインアカウントやgMSA)自体に接続先の権限を与えれば、スクリプトからパスワードが消えます。gMSAならパスワード管理そのものをOSに任せられます。910
  • ログとトランスクリプトへの漏えいを設計に含めます。スクリプトブロックログを有効にすると、スクリプトで使った資格情報などの機微データがイベントログに書かれうると公式ドキュメントが警告しています。平文パスワードをコマンドラインに打った時点で、記録に残る前提で考えます。11

2. 平文の何が問題か ── 漏えい経路はコピーの数だけある

まず、書き換え対象となる典型パターンを確認しておきます。

# アンチパターン: どちらも「平文がスクリプトに残る」点で同じ
$password = "P@ssw0rd123"

# SecureStringに変換しても、元の平文は1行目に書かれたまま。
# PSScriptAnalyzerはこの -AsPlainText の使い方をエラーとして検出する
$secure = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('svc-transfer', $secure)

パスワードの直書きが危険な理由は、「悪意ある侵入者に読まれるかもしれない」だけではありません。スクリプトという成果物の性質上、正規の運用をしているだけでコピーが増殖することです。

コピーが生まれる場所 何が起きるか
Gitリポジトリ 一度コミットしたパスワードは履歴に永久保存。後からファイルを直しても履歴には残る
共有フォルダ 読み取り権限のある全員+バックアップ+世代コピーに拡散
メール・チャット 「このスクリプト使って」と添付した瞬間に制御不能
イベントログ スクリプトブロックログが有効なら、実行されたコードの内容がログに記録される11
トランスクリプト Start-Transcriptや組織のトランスクリプション設定が、画面に流れた内容を記録する11

この構造が意味するのは、平文パスワードの対策は「ファイルを見られないようにする」ことでは達成できない、ということです。アクセス権をどれだけ絞っても、Git履歴とバックアップまでは締められません。パスワードをスクリプトの外へ、暗号化された保管場所へ出すことが本筋です。この考え方は、.NETアプリの設定ファイルについて「Windowsアプリの機密情報保存 - DPAPIで平文設定を避ける」で書いたことと同じで、PowerShellでも原則は変わりません。

なお、平文をその場でSecureStringに変換するConvertTo-SecureString "P@ssw0rd" -AsPlainText -Forceは解決策ではありません。PSScriptAnalyzer(公式の静的解析ツール)はこの書き方をエラー(Severity: Error)として検出します。暗号化を迂回して平文をメモリに晒すうえ、元の平文がスクリプト内に残り続けるからです。1

3. 道具の実像 ── PSCredential・SecureString・その限界

3.1. Get-CredentialとPSCredential

対話的なスクリプトの基本形はこれだけです。

# ユーザー名とパスワードの入力を求め、PSCredentialオブジェクトとして受け取る
$cred = Get-Credential -Message '基幹DBの接続アカウントを入力してください'

# -Credentialパラメーターを持つコマンドにそのまま渡せる
Invoke-Command -ComputerName APPSV01 -Credential $cred -ScriptBlock { hostname }

Get-Credentialはユーザー名とパスワードの入力を促し、PSCredentialオブジェクトを返します。Windows PowerShell 5.1ではダイアログ、PowerShell 6以降ではコンソールでの入力になります。3 パスワードはPSCredentialの中でSecureStringとして保持され、画面には表示されません。「人がその場で入力する」運用が許される場面では、これ以上複雑なことをする必要はありません。

自作関数を作る側は、パスワードを[string]で受けず、[PSCredential]の-Credentialパラメーターを受けるように設計します。書き方の詳細は公式の解説「Add Credential support to PowerShell functions」にまとまっています。2

3.2. SecureStringの実像 ── 「非推奨」の正しい受け止め方

SecureStringには知っておくべき事実が3つあります。

  • .NET公式は「新規開発では使わないことを推奨」しています。内部配列の暗号化はWindowsでのみ行われ、非Windowsプラットフォームでは内部ストレージが暗号化されません。また使う瞬間には結局平文表現へ変換されるため、露出時間を短くする効果しかありません。推奨される代替は「プロセス外に保存された資格情報への不透明なハンドル」、つまりOSの資格情報ストアやKey Vaultのような仕組みです。4
  • それでもPowerShellの標準装備はSecureString前提です。PowerShellは互換性のためSecureStringをサポートし続けており、コンソールやログへの偶発的な露出を避ける用途で今も使われています。平文文字列よりは安全である、という位置づけです。5
  • 簡単に平文へ戻せます。PowerShell 7ではConvertFrom-SecureString -AsPlainTextの一発で平文になります。12 SecureStringは「読めない金庫」ではなく「うっかり見えないための封筒」程度に考えるのが実像に合っています。

実務の結論はこうです。SecureStringを理由に複雑な自作暗号化へ走らない。PowerShellの道具(Get-Credential、SecretManagement)が要求する形式として使い、保護の本体はDPAPIやボールトなどプロセス外の仕組みに置く。

4. 無人実行の定番 ── Export-ClixmlのDPAPI保存と「同一ユーザー・同一マシン」の壁

タスクスケジューラで動く無人スクリプトは、Get-Credentialで人に聞くわけにいきません。最小構成の実用解が、Export-Clixmlによる資格情報ファイルです。

# --- 準備(1回だけ、タスクの実行アカウントで実行する) ---
$cred = Get-Credential -Message '連携用アカウント'
$cred | Export-Clixml -Path 'D:\Jobs\secrets\transfer.credential'

# --- 本番スクリプト(無人実行) ---
$cred = Import-Clixml -Path 'D:\Jobs\secrets\transfer.credential'
# 例: 別資格情報が必要な共有への接続やリモート実行に使う
Invoke-Command -ComputerName FILESV01 -Credential $cred -ScriptBlock { Get-ChildItem D:\Export }

Export-Clixmlは資格情報オブジェクトをWindowsのDPAPI(データ保護API)で暗号化して保存します。復号できるのは、保存したユーザーアカウントが、保存したそのコンピューター上で開いたときだけです。エクスポートしたファイルは別のマシンや別のユーザーでは使えません。613 ファイルが持ち出されても開けない、という性質が無人実行の保存先として都合がよいわけです。

ただし、この「同一ユーザー・同一マシン限定」は保護であると同時に運用の落とし穴です。

  • タスクスケジューラの実行アカウントと合わせる必要があります。自分のアカウントで作った.credentialファイルは、タスクがサービスアカウントで動いた瞬間に復号できなくなります。準備作業は必ず「タスクの実行アカウントとして」行います(そのアカウントでPowerShellを起動して保存する)。タスクの実行アカウントとログオン種別の考え方は「タスクスケジューラのタスクが実行されない・0x1で終わる」で詳述しています。
  • サーバーの入れ替え・アカウント変更で必ず作り直しになります。「移行したら動かない」の定番原因なので、準備手順をスクリプト化してリポジトリに残しておきます(パスワード自体はもちろん含めません)。
  • 同一アカウントで動くプロセスからは復号できます。DPAPIはそのユーザーとして動くコードには開かれているため、実行アカウントに不要なソフトウェアを同居させない、アカウントの権限を最小にする、という周辺の衛生管理は引き続き必要です。
  • 非Windowsでは暗号化されません。macOS/Linuxでは実質平文(Unicode文字配列)で出力されると公式ドキュメントに明記されています。6

なお、ConvertFrom-SecureStringに-Keyを指定してAES暗号化する方法もありますが、こんどは「鍵ファイルをどう守るか」という同じ問題が一段ずれて残るだけになりがちです。12 マシンをまたぐ必要が出た時点で、次章のボールトか、第6章の「持たない設計」に進むべきです。

5. 秘密が増えてきたら ── SecretManagementとSecretStore

接続先が増え、APIキーやトークンも混ざってくると、.credentialファイルの散在が管理限界を迎えます。そこで使うのがSecretManagementモジュールです。これは秘密の保管場所(ボールト)への統一インターフェースで、実際の保存は拡張ボールトが担います。ローカル保存のSecretStore(Microsoft製)のほか、Azure Key Vault、KeePassなどの拡張ボールトを同じコマンドで扱えます。714

# 初回のみ: モジュール導入とボールト登録
Install-Module Microsoft.PowerShell.SecretManagement, Microsoft.PowerShell.SecretStore
Register-SecretVault -Name SecretStore -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault

# 秘密の登録(初回アクセス時にボールトのパスワードを設定する)
Set-Secret -Name TransferJobCred -Secret (Get-Credential)

# スクリプト側: 名前で取り出す。保存先が変わってもこの行は変わらない
$cred = Get-Secret -Name TransferJobCred

秘密の値にはPSCredentialやSecureStringのほか、文字列・バイト配列・ハッシュテーブルも保存でき、初回アクセス時にボールト自体を保護するパスワードの設定を求められます。15 利点は、スクリプトから「どこに保存されているか」の知識が消えることです。開発機ではSecretStore、本番ではAzure Key Vault(Az.KeyVaultモジュールが拡張ボールトを提供)という差し替えが、Register-SecretVaultの構成変更だけで済みます。167

一方で、無人実行に持ち込むときの注意が3つあります。

  • SecretStoreは既定で対話的にボールトパスワードを要求します。そのままタスクスケジューラに載せるとプロンプト待ちで止まります。公式ドキュメントは無人実行向けに、InteractionをNoneにし、DPAPI保護ファイル(Export-Clixml)に退避したボールトパスワードをUnlock-SecretStoreで渡す構成を案内しています。8 つまりボールトの鍵は結局DPAPIで守ることになり、前章の同一ユーザー・同一マシン制約を引き継ぎます。パスワード要求自体を無効化(Authentication None)する構成も可能ですが、鍵がファイルシステム権限だけで守られることになるため、強い保護が必要な用途では推奨されていません。17
  • gMSAなどの管理されたアカウントでは動きません。SecretManagementはプロファイル($env:LOCALAPPDATA)とDPAPIに依存しており、プロファイルを持たないWindowsの管理されたアカウントを現在サポートしていないと明記されています。14 gMSAで動くジョブに秘密を持たせたい場合は、この組み合わせは選べません(そもそもgMSAなら秘密を持たない設計に寄せられることが多い ── 次章)。
  • SecretManagement/SecretStoreは機能完成(feature complete)扱いで、積極的な新機能開発は終了しています。セキュリティ修正と重大バグの対応は継続されるため使うこと自体は問題ありませんが、公式も「秘密の性質はパスワードレスや連携資格情報へ変わりつつある」としており、長期の設計では認証方式そのものの見直し(Entra IDのマネージドID等)も視野に入れるべきです。7

Windowsの資格情報マネージャー(Credential Manager)をボールトとして使うコミュニティ拡張も存在します。7 cmdkeyで登録した資格情報が自動で使われる仕組みなど、資格情報マネージャー自体の挙動は「ネットワークドライブとUNCパスの落とし穴」で触れたとおり、こちらもユーザープロファイル単位である点は同じです。

6. 最優先の現実解 ── そもそも資格情報を持たない

ここまで「どう安全に保存するか」を積み上げてきましたが、実は無人実行の一番きれいな答えは保存方法の工夫ではありません。スクリプトが資格情報を持つ必要をなくすことです。

Windowsのタスクやサービスは、実行アカウントのセキュリティコンテキストで動きます。接続先がWindows認証で守られているなら ── 共有フォルダのACL、SQL ServerのWindows認証、社内APIのWindows統合認証 ── 実行アカウント自身に接続先の権限を与えれば、スクリプトにはパスワードもGet-Secretも一切登場しません。認証はKerberosが実行アカウントの身元で勝手にやってくれます。

この構成を支えるのがgMSA(グループ管理サービスアカウント)です。gMSAはドメインの管理されたアカウントで、パスワード管理をWindows OSが引き受けます。9 パスワードは240バイトのランダム生成で30日ごとにOSが自動変更するため、人間は誰もパスワードを知らず、期限切れによる停止も起きません。10 そしてgMSAは、Windowsサービスだけでなくタスクスケジューラのタスクにも使えます。18

判断の優先順位を整理すると、こうなります。

  1. 接続先がWindows認証にできるなら、実行アカウント(ドメインアカウント/gMSA)への権限付与で資格情報を消す。ドメイン環境の無人ジョブはまずこれを検討します。9
  2. それが無理な相手(SQL認証のDB、APIキー、ワークグループのNASなど)だけ、秘密を保存する。単発ならExport-ClixmlのDPAPI保存、複数あるならSecretManagement+SecretStore。68
  3. クラウド資源への接続は、キーの保存よりマネージドID/フェデレーション資格情報の利用を優先する。保存する場合もAzure Key Vaultのような専用ボールトへ。167

リモートのサーバーに対して資格情報を明示的に渡して処理を実行する場面では、PowerShell Remotingの認証の仕組みも絡みます。同時公開の「PowerShell Remoting/WinRM入門」を参照してください。

7. ログ・トランスクリプトに秘密を残さない

保存を固めても、実行時の記録から漏れては意味がありません。押さえるべきは2点です。

第一に、PowerShellは実行内容を記録する機能を複数持っており、組織設定で有効になっていることがあります。スクリプトブロックログを有効にすると、処理したすべてのスクリプトブロックの内容がイベントログに記録されます。公式ドキュメントは「スクリプトログを有効にすると、スクリプトで使われた資格情報や機微データがイベントログに書かれうる」と明示的に警告し、診断以外の用途では保護されたイベントログ(Protected Event Logging)の併用を推奨しています。11 トランスクリプション(操作の書き起こし)も同様で、コンソールに流れた内容はファイルに残ります。

第二に、だからこそ「平文がコマンドラインや画面を通過しない」書き方を徹底します。

  • パスワードを引数で受け取る設計にしない。.\job.ps1 -Password "P@ssw0rd"と打った時点で、ログ・履歴・プロセス一覧に残る前提で考えます。受けるならPSCredentialかSecureStringで受けます。2
# 自作スクリプトの受け口の作法: パスワードを[string]で受けない
[CmdletBinding()]
param(
    # 資格情報はPSCredentialで受ける。省略時はGet-Credentialで対話取得、
    # 無人実行ではImport-ClixmlやGet-Secretの結果を渡す
    [Parameter(Mandatory)]
    [System.Management.Automation.PSCredential]$Credential
)
# 秘密を含む変数はデバッグ出力しない。出すのはユーザー名まで
Write-Verbose "接続アカウント: $($Credential.UserName)"
  • 秘密を含む変数をWrite-HostやWrite-Verboseでデバッグ出力しない。トラブルシューティング時の「一時的なつもり」の出力が、トランスクリプトに永続化します。
  • 例外メッセージへの混入に注意する。接続文字列を組み立ててからエラーを投げると、catchしたログに接続文字列ごと記録されがちです。エラー処理でログに何を書くかの設計は「PowerShellのエラー処理と再実行設計」も併せてどうぞ。

8. 実務の定石(判断表)

状況 推奨 判断の目安
人がその場で実行する Get-Credential 保存しないのが一番安全。PSCredentialで受けて-Credentialへ渡す3
ドメイン内の無人ジョブ(接続先がWindows認証) 実行アカウント/gMSAへの権限付与 資格情報を持たない設計を最優先。gMSAはタスクスケジューラでも使える918
無人ジョブで秘密が1〜2個 Export-ClixmlのDPAPI保存 タスクの実行アカウント自身で保存。マシン・アカウント変更で作り直し6
無人ジョブで秘密が多数・保存先を将来差し替えたい SecretManagement+SecretStore ボールトパスワードはDPAPI保存+Unlock-SecretStoreで供給。gMSAでは使えない814
クラウド資源・複数サーバーで共有する秘密 Azure Key Vault(+SecretManagement) マシン局所のDPAPIでは共有できない。集中管理と監査が必要になったら16
スクリプト内の平文+ConvertTo-SecureString 書き換え対象 PSScriptAnalyzerがエラー判定する筋の悪い形。上のいずれかへ移行する1

迷ったら「持たない > マシンに固定して持つ(DPAPI) > ボールトで持つ」の順で、上から検討してください。

9. まとめ

  • 平文パスワードの本質的な問題は、Git履歴・共有フォルダ・ログというコピーの増殖経路すべてが漏えい経路になることです。アクセス権の管理では守り切れません。
  • 対話実行はGet-Credential+PSCredentialで十分です。パスワードを[string]で受ける自作関数は作らないでください。
  • SecureStringは.NET公式が新規開発非推奨とする一方、PowerShellの標準的な受け渡し形式として残っています。「うっかり露出を防ぐ封筒」と割り切り、保護の本体は外部の仕組みに置きます。
  • Export-ClixmlのDPAPI保存は「同一ユーザー・同一マシン限定」。タスクスケジューラの実行アカウント自身で保存ファイルを作るのが要点で、非Windowsでは暗号化されません。
  • SecretManagement+SecretStoreは複数の秘密の一元管理に有効ですが、無人実行ではボールトパスワードの供給設計が必要で、gMSAでは使えません。機能完成扱いである点も踏まえて採用します。
  • 最優先は資格情報を持たない設計です。Windows認証+実行アカウント(gMSA)への権限付与で、スクリプトからパスワードを消せないかを最初に検討してください。
  • スクリプトブロックログやトランスクリプトには機微データが残りえます。平文がコマンドライン・画面・例外メッセージを通過しない書き方を徹底します。

関連記事

関連する相談領域

合同会社小村ソフトでは、運用スクリプト・定期バッチに埋め込まれた資格情報の棚卸しと安全な保管への移行、gMSAを含む実行アカウント設計、無人実行ジョブのセキュリティレビューを扱っています。「動いているから触れない」まま放置された平文パスワードの整理からご相談ください。

参考リンク

  1. Microsoft Learn, AvoidUsingConvertToSecureStringWithPlainText. PSScriptAnalyzerがConvertTo-SecureStringの-AsPlainText使用をエラー(Severity: Error)として検出すること、暗号化を迂回して機微情報を平文でメモリに晒すこと、代替としてRead-Host -AsSecureStringやSecretStoreモジュールが挙げられていることについて。  2 3

  2. Microsoft Learn, Add Credential support to PowerShell functions. 自作関数にPSCredentialパラメーターを追加する方法、平文パスワードがさまざまなログに記録されるためConvertTo-SecureString -AsPlainTextの使用時に警告される理由について。  2 3

  3. Microsoft Learn, Get-Credential. Get-Credentialがユーザー名とパスワードの入力を促してPSCredentialオブジェクトを返すこと、Windows PowerShell 5.1ではダイアログ・PowerShell 6以降ではコンソールで入力を求めること、-Credentialパラメーターを持つコマンドに渡して使うことについて。  2 3

  4. Microsoft Learn, SecureString Class. .NET(Core)の新規開発でSecureStringを使わないことが推奨されていること、暗号化がWindowsでのみ行われ非Windowsでは内部ストレージが暗号化されないこと、使用時には平文表現への変換が必要なこと、推奨代替がプロセス外に保存された資格情報への不透明なハンドルであることについて。  2

  5. Microsoft Learn, Advisory Development Guidelines. .NETがSecureStringの新規利用を推奨しない一方で、PowerShellは後方互換性のためSecureStringをサポートし続けていること、平文文字列よりは安全であり、コンソールやログへの偶発的露出を避けるために使われていること、容易に平文へ変換できるため注意して使うべきことについて。  2

  6. Microsoft Learn, Export-Clixml. Export-Clixmlが資格情報オブジェクトをWindowsのDPAPIで暗号化して保存すること、復号できるのが保存したユーザーアカウント・保存したコンピューター上のみでありエクスポートファイルを他のマシン・他のユーザーで使えないこと、非Windows(macOS/Linux)では暗号化されず実質平文で出力されることについて。  2 3 4 5

  7. Microsoft Learn, Overview of the SecretManagement and SecretStore modules. SecretManagementが拡張ボールトへの統一インターフェースであること、SecretStoreがローカルファイルに暗号化保存するクロスプラットフォームの拡張ボールトであること、Azure Key Vault・KeePass・資格情報マネージャー(CredMan)などの拡張ボールトが存在すること、Secretモジュール群が機能完成扱いで積極開発を終了しセキュリティ修正のみ継続されることについて。  2 3 4 5 6

  8. Microsoft Learn, Use the SecretStore in automation. 無人実行向けにSecretStoreのInteractionをNoneに構成すること、ボールトパスワードをExport-ClixmlでDPAPI暗号化したファイルに保存しUnlock-SecretStoreで解錠する構成、これがWindows限定の解決策であることについて。  2 3 4

  9. Microsoft Learn, Group Managed Service Accounts overview. gMSAが自動パスワード管理とSPN管理の簡素化を提供する管理されたドメインアカウントであり、パスワード管理を管理者ではなくWindows OSが担うことについて。  2 3 4

  10. Microsoft Learn, Secure group managed service accounts. gMSAのパスワードが240バイトのランダム生成であること、OSが30日ごとに自動変更するためパスワード変更の計画やサービス停止が不要になること、オンプレサービスのアカウント種別としてgMSAの使用が推奨されることについて。  2

  11. Microsoft Learn, about_Logging_Windows. スクリプトブロックログを有効にするとPowerShellが処理する全スクリプトブロックの内容がイベントログに記録されること、ログレベルを上げるとスクリプトで使われた資格情報などの機微データがログに含まれうること、その保護のためのProtected Event Loggingについて。  2 3 4

  12. Microsoft Learn, ConvertFrom-SecureString. SecureStringを暗号化された標準文字列に変換できること、鍵を指定しない場合はWindowsのDPAPIが、Key/SecureKey指定時はAESが使われること、-AsPlainTextで平文文字列へ直接変換できることについて。  2

  13. Microsoft Learn, Import-Clixml. Import-ClixmlでExport-Clixmlが保存した資格情報・セキュア文字列を復元できること、これによりスクリプト内に平文パスワードを書くリスクを避けられることについて。 

  14. Microsoft Learn, Understanding the SecretManagement module. SecretManagementが登録済み拡張ボールト経由で秘密を保存・取得する仕組みであること、ボールト登録がユーザーコンテキスト単位であること、$env:LOCALAPPDATAとDPAPIへの依存によりWindowsの管理されたアカウント(managed accounts)では現在動作しないことについて。  2 3

  15. Microsoft Learn, Get started with the SecretStore module. Register-SecretVaultでのSecretStore登録、Set-Secret/Get-Secret/Get-SecretInfoの基本操作、初回アクセス時にボールトのパスワード設定を求められることについて。 

  16. Microsoft Learn, Use Azure Key Vault in automation. Az.KeyVault 3.3.0以降がSecretManagement拡張を含み、Register-SecretVaultでAzure Key VaultをSecretManagementのボールトとして登録してGet-Secret等で操作できることについて。  2 3

  17. Microsoft Learn, Understanding the security features of SecretManagement and SecretStore. パスワード認証を完全に無効化した場合、復号鍵がファイルシステム権限のみで保護され、強いセキュリティ保護が必要なシステムには推奨されないことについて。 

  18. Microsoft Learn, Manage group Managed Service Accounts. gMSAをサービスコントロールマネージャー構成のサービス、IISアプリケーションプール、タスクスケジューラのタスクで使用できることについて。  2

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

この記事は次のサービスページにつながります。近い入口からご覧ください。

よくある質問

この記事のテーマについて、相談時によくある質問をまとめています。

PowerShellスクリプトにパスワードを平文で書いてはいけないのはなぜですか?
スクリプトはコピーされ、共有され、履歴に残る前提の成果物だからです。Gitに一度コミットすれば履歴から消すのは困難で、共有フォルダに置けば読み取り権限のある全員に見え、スクリプトブロックログやトランスクリプトにはコマンドの内容がそのまま記録されます。つまり平文パスワードは「ファイルが見えた時点で漏えい確定」の構造を作ってしまいます。まず漏えい経路を締めるのではなく、パスワードをスクリプトの外の保護された場所へ出すことが対策の本筋です。
Export-Clixmlで保存した資格情報はどこまで安全ですか?
WindowsではDPAPI(データ保護API)で暗号化され、保存したユーザーアカウントかつ同じコンピューター上でしか復号できません。ファイルが盗まれても他のマシン・他のユーザーでは開けないため、無人実行用の保存先としては実用的な選択肢です。ただし同一アカウントで動くプロセスからは復号できるので万能ではなく、またmacOSやLinuxでは暗号化されず実質平文で出力される点に注意が必要です。タスクスケジューラから使う場合は、タスクの実行アカウント自身で保存ファイルを作る必要があります。
SecureStringは今でも使うべきですか?
.NETの公式ドキュメントは新規開発でのSecureString使用を推奨しないと明記しています。暗号化はWindowsでしか行われず、非Windowsでは内部が暗号化されません。また使う瞬間には結局平文へ戻す必要があります。一方でPowerShellの世界では、Get-CredentialやSecretManagementなど標準の道具がSecureStringを前提にしており、平文文字列で持ち回るよりは露出が減るため、当面は「PowerShellの標準的な受け渡し形式」として付き合うのが現実的です。自前で暗号化の仕組みを作る材料にはしないでください。
タスクスケジューラの無人実行でSecretStoreを使うとパスワード入力で止まりませんか?
既定構成のままでは止まります。SecretStoreは既定でボールトパスワードを要求し、対話プロンプトを出すためです。無人実行では、Interactionを None にし、ボールトパスワードをDPAPI保護のファイル(Export-Clixml)から読み込んでUnlock-SecretStoreで解錠する構成が公式ドキュメントで案内されています。ただしこれは「ボールトの鍵をDPAPIで守る」構成であり、結局DPAPIの制約(同一ユーザー・同一マシン)を引き継ぎます。その手前で、gMSAや実行アカウントの権限付与で資格情報自体を不要にできないかを先に検討してください。
そもそも資格情報を保存しない方法はありますか?
あります。むしろそれが第一選択です。Windowsのタスクやサービスは実行アカウントの権限で動くため、接続先(共有フォルダ、SQL ServerのWindows認証など)に実行アカウント自身の権限を付与すれば、スクリプトはパスワードを一切持たずに済みます。実行アカウントをgMSA(グループ管理サービスアカウント)にすれば、パスワードは240バイトのランダム値をOSが30日ごとに自動更新し、人間は誰もパスワードを知らない状態を作れます。gMSAはタスクスケジューラのタスクにも使えます。

著者プロフィール

記事の著者プロフィールページです。

小村 豪

合同会社小村ソフト 代表

Windows ソフト開発、技術相談、不具合調査を中心に、既存資産が残る案件や原因が見えにくい障害調査に強みがあります。

ブログ一覧に戻る