在試圖從受保護的HTTP源下載文件使用下面的代碼返回401未經授權:PowerShell的System.Net.WebClient認證
$pfile = "\\some\local\leaf\path"
$user = "MyUserName"
$pwdIn = read-host -assecurestring | convertfrom-securestring | out-file $pfile
$pwdOut = get-content $pFile| convertto-securestring
$url="http://path.to/file"
$file = "\\localpath\to\file"
$webclient = new-object System.Net.WebClient
$webclient.Credentials = new-object System.Net.NetworkCredential($user, $pwdOut)
$webclient.DownloadFile($url,$file)
所以不跳過寫像這樣的密碼文件的步驟:
$pwd = read-host -assecurestring
...
$webclient.Credentials = new-object System.Net.NetworkCredential($user, $pwd)
但是,跳過SecureString的創建工作得很好:
$pwd = read-host
...
$webclient.Credentials = new-object System.Net.NetworkCredential($user, $pwd)
以上代碼不會返回任何其他錯誤。在頂部測試原始代碼版本時,我驗證了目標密碼文件的存在性和明顯的結構有效性。整個代碼都在單個腳本中,因此convertto和convertfrom在執行期間具有相同的環境。我在x86和64位PowerShell中都試過了。
事實上,我甚至可以安全字符串轉換回用正確的基本字符串與Web客戶端使用它:
$pwdtmp = get-content $pFile| convertto-securestring
$pwdOut = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwdtmp))
$webclient.Credentials = new-object System.Net.NetworkCredential($user, $pwdOut)
因此,這個問題必須要使用與System.Net.NetworkCredential類SecureString的,但是http://msdn.microsoft.com/en-us/library/system.net.networkcredential.aspx,以及我發現的一些例子表明SecureString應該作爲第二個參數。
雖然寫這篇文章,其實我已找到了解決辦法:
$user = "user"
$pwd = read-host -assecurestring
$creds = New-Object System.Management.Automation.PSCredential `
-ArgumentList $user, $pwd
$webclient.Credentials = new-object System.Net.NetworkCredential($user, $Creds.GetNetworkCredential().Password)
$webclient.DownloadFile($url,$file)
但不是解釋爲什麼SecureString的類型不工作,而PSCredential.Password一樣。執行$ creds |通用清楚地表明,$ creds.Password也是事實SecureString的:
類型名:System.Management.Automation.PSCredential
名稱MemberType定義
---- - --------- ----------等於方法bool等於(System.Object obj)
GetHashCode方法int GetHashCode()
GetNetworkCredential方法System.Net.NetworkCredential GetNetworkCredential() GetType方法類型GetType () ToString方法字符串的ToString()
Password屬性爲System.Security.SecureString密碼 {獲得;}
是怎麼回事?
我猜$ Creds.GetNetworkCredential()。密碼的工作原理是因爲它返回一個純字符串。那麼爲什麼不保證字符串的工作? – Yevgeniy