目的
Invoke-RestMethod コマンドレットや Invoke-WebRequest コマンドレットをユーザ認証のあるプロキシサーバを越えて使用するための設定を行う。
成功例
$proxyServer = "http://xxx.xxx.xxx:8080" # 未設定の場合はIEの設定を利用する
$proxyUser = "xxxxx" # 未設定の場合は認証なしとみなす
$proxyPassword= "xxxxx" # 未設定の場合はプロンプトする
if (-not $proxyServer) {
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
if ($proxy) { $proxyServer = $proxy.GetProxy("http://example.com").AbsoluteUri }
}
if ($proxyServer) {
$proxy = New-Object System.Net.WebProxy $proxyServer, $True
if ($proxyUser) {
if ($proxyPassword) {
$securePassword = ConvertTo-SecureString $proxyPassword -AsPlainText -Force
$proxy.Credentials = New-Object -TypeName System.Management.Automation.PSCredential $proxyUser,$securePassword
} else {
$proxy.Credentials = Get-Credential -UserName $proxyUser -Message "プロキシサーバのパスワードを入力して下さい。"
}
}
[System.Net.WebRequest]::DefaultWebProxy = $proxy
}
失敗例(本当はこちらを使いたい)
なぜ失敗するのか不明(環境依存のバグかも。ネット上に Win7, Win8.1 で失敗、Win10 で成功との情報あり)。
(2019.7.23更新) Win10での成功を確認しました。
$proxyServer = "http://xxx.xxx.xxx:8080" # 未設定の場合はIEの設定を利用する
$proxyUser = "xxxxx" # 未設定の場合は認証なしとみなす
$proxyPassword= "xxxxx" # 未設定の場合はプロンプトする
if (-not $proxyServer) {
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
if ($proxy) { $proxyServer = $proxy.GetProxy("http://example.com").AbsoluteUri }
}
if ($proxyServer) {
if ($proxyUser) {
if ($proxyPassword) {
$securePassword = ConvertTo-SecureString $proxyPassword -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $proxyUser,$securePassword
} else {
$credential = Get-Credential -UserName $proxyUser -Message "プロキシサーバのパスワードを入力して下さい。"
}
$PSDefaultParameterValues = @{ "Invoke-RestMethod:Proxy"=$proxyServer; "Invoke-RestMethod:ProxyCredential"=$credential;
"Invoke-WebRequest:Proxy"=$proxyServer; "Invoke-WebRequest:ProxyCredential"=$credential }
} else {
$PSDefaultParameterValues = @{ "Invoke-RestMethod:Proxy"=$proxyServer;
"Invoke-WebRequest:Proxy"=$proxyServer }
}
}
追記(2019.7.27)
スクリプト内へのパスワード記載(平文)を避ける方法について3つ程考察してみます。
方法1 既定の資格情報(DefaultCredentials)の利用
プロキシサーバの認証が、Windowsと共通であれば、既定の資格情報が利用できますので、Invoke-RestMethod コマンドレットや Invoke-WebRequest コマンドレットのパラメータとして ProxyCredential
の代わりに-ProxyUseDefaultCredentials
を指定することができます。
方法2 資格情報マネージャーに格納された資格情報の利用
プロキシサーバの認証情報を資格情報マネージャーに格納されているキャッシュから取得します。資格情報マネージャーの情報にアクセスするためには、advapi32.dll の ReadCredW 関数を使う必要あります。
PowerShell から ReadCredW を呼び出して Credential オブジェクトとして返す関数の例が、ここやここにありますが、数行で実装という訳にはいきません。手軽に使うには、ちょっと...って感じですね。
(2020.10.24追記)
WinRTを利用して $null = [Windows.Security.Credentials.PasswordVault,.,ContentType=WindowsRuntime]; $vault = (New-Object Windows.Security.Credentials.PasswordVault).RetrieveAll(); $vault.RetrievePassword(); $vault
で取得できるようです。
方法3 暗号化された文字列としてスクリプト内に埋め込む
ConvertFrom-SecureString コマンドレットで、$securePassword を暗号化された文字列に変換して、それをスクリプト内に保存します。SecureString に戻すには ConvertTo-SecureString コマンドレットを使用します。
クリエイティブ・コモンズ 表示 - 継承 4.0 国際