我有一个 PowerShell 脚本,用于执行两件事:检查Last Checked
Windows 更新的值,并枚举所有驱动器并检查这些驱动器上的剩余空间,用于远程服务器。
该函数的预期输出是:
servername
----------
Last Checked for Windows Update:
01/18/2021 08:12:46
Disk Size Free %Free
C: 501.46 238.06 47.47%
E: 300.00 140.15 46.72%
当针对与我位于同一域的计算机运行时,该脚本完全按预期工作。但是,我们有少数计算机不在同一域中,并使用本地管理员帐户进行访问。当针对其中一台计算机运行脚本时,Windows 更新部分失败,但磁盘空间部分成功运行。
脚本的两个部分共享相同的PsCredential
,但磁盘空间部分是一个Get-WmiObject
使用参数的函数-ComputerName
,而 Windows 更新部分位于一个带有和的函数-Credential
内部Invoke-Command
-ComputerName
-Credential
我不确定为什么相同的方法PsCredential
对一个有效而对另一个失败,也许是不同的身份验证路线?
我从 Windows 更新部分得到的错误是:
[servername] Connecting to remote server servername failed with the following error message : WinRM cannot process the
request. The following error with errorcode 0x80090311 occurred while using Kerberos authentication: We can't sign you
in with this credential because your domain isn't available. Make sure your device is connected to your organization's
network and try again. If you previously signed in on this device with another credential, you can sign in with that
credential.
Possible causes are:
-The user name or password specified are invalid.
-Kerberos is used when no authentication method and no user name are specified.
-Kerberos accepts domain user names, but not local user names.
-The Service Principal Name (SPN) for the remote computer name and port does not exist.
-The client and remote computers are in different domains and there is no trust between the two domains.
After checking for the above issues, try the following:
-Check the Event Viewer for events related to authentication.
-Change the authentication method; add the destination computer to the WinRM TrustedHosts configuration setting or
use HTTPS transport.
Note that computers in the TrustedHosts list might not be authenticated.
-For more information about WinRM configuration, run the following command: winrm help config. For more
information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (servername:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : AuthenticationFailed,PSSessionStateBroken
脚本如下:
$server = "servername"
$adminaccount = $server + "\localadminaccount"
$PASSWORD = ConvertTo-SecureString "localadminpassword" -AsPlainText -Force
$UNPASSWORD = New-Object System.Management.Automation.PsCredential $adminaccount, $PASSWORD
$out = ""
$out += $server + "`n----------`n"
$out += Invoke-Command -ComputerName $server -Credential $UNPASSWORD -ScriptBlock {
Function Get-LocalTime($UTCTime) {
$strCurrentTimeZone = (Get-WmiObject win32_timezone).StandardName;
$TZ = [System.TimeZoneInfo]::FindSystemTimeZoneById($strCurrentTimeZone);
Return [System.TimeZoneInfo]::ConvertTimeFromUtc($UTCTime, $TZ);
}
$updateInfo = "Last Checked for Windows Update: `n";
$updateInfo += Get-LocalTime $(New-Object -ComObject Microsoft.Update.AutoUpdate).Results.LastSearchSuccessDate;
$updateInfo += "`n`n"
Return $updateInfo
}
$out += "Disk`tSize`tFree`t%Free`n"
$disks = Get-WmiObject Win32_LogicalDisk -computername $server -filter DriveType=3 -Credential $UNPASSWORD
foreach ($objdisk in $disks)
{
$size = "{0:N2}" -f ($objDisk.Size/1GB)
$free = "{0:N2}" -f ($objDisk.FreeSpace/1GB)
$freePercent="{0:P2}" -f ([double]$objDisk.FreeSpace/[double]$objDisk.Size)
$out += $objDisk.DeviceID + "`t"
$out += $size + "`t"
$out += $free + "`t"
$out += $freePercent + "`n"
}
$out
答案1
据我所知,Invoke-Command
如果计算机不在同一个域中,则需要该计算机成为受信任的主机,因此解决方案是将计算机添加为受信任的主机。
为了不不必要地干扰受信任的主机,我以只会暂时影响受信任主机的方式实现了解决方案:
之前Invoke-Command
(添加受信任的主机):
$curHosts = (Get-ChildItem WSMan:\localhost\Client\TrustedHosts).Value
Set-Item WSMan:\localhost\Client\TrustedHosts -Value $server -Concatenate -Force
之后Invoke-Command
(重置受信任的主机):
Set-Item WSMan:\localhost\Client\TrustedHosts $curHosts -Force