【问题标题】:PowerShell script fails to authenticate user when running Invoke-CommandPowerShell 脚本在运行 Invoke-Command 时无法对用户进行身份验证
【发布时间】:2018-01-31 06:31:23
【问题描述】:

我最近创建了一个小脚本,当我向脚本提供学校的 4 位站点代码时,它允许我获取每个学校站点的 2 台服务器的磁盘大小和可用空间。

首先,它从 .csv 文件中提取有关站点的信息,然后使用该信息将 DC FQDN 主机名和 .10 服务器的字符串组合在一起。

然后它会请求我用来获取磁盘信息的提升访问帐户的密码。

当脚本创建脚本块,然后使用 Invoke-Command 并将脚本块发送到服务器时,我遇到了一个问题,并将信息提供回 PowerShell 对象。

提供的错误如下:

[{ServerName}] 连接到远程服务器 {ServerName} 失败,原因是 以下错误消息:WinRM 无法处理该请求。以下 使用 Kerberos 身份验证时出现错误代码 0x80090311 的错误: 当前没有可用于服务登录请求的登录服务器。 可能的原因有: - 指定的用户名或密码无效。 -Kerberos 在没有指定身份验证方法和用户名时使用。 -Kerberos 接受域用户名,但不接受本地用户名。 - 远程计算机名称和端口的服务主体名称 (SPN) 不存在。 -客户端和远程计算机在不同的域中,没有信任 两个域之间。 检查上述问题后,请尝试以下操作: - 检查事件查看器以获取与身份验证相关的事件。 -改变认证方式;将目标计算机添加到 WinRM TrustedHosts 配置设置或使用 HTTPS 传输。 请注意,TrustedHosts 列表中的计算机可能未经过身份验证。 - 有关 WinRM 配置的更多信息,请运行以下命令: winrm 帮助配置。有关详细信息,请参阅 about_Remote_Troubleshooting 帮助主题。 + CategoryInfo : OpenError: ({ServerName}:String) [], PSRemotingTransportException + FullyQualifiedErrorId : AuthenticationFailed,PSSessionStateBroken

我尝试过的事情:

  • 重置我的密码

  • 将身份验证类型更改为基本

  • 让其他人尝试同样的事情 - 有些人有同样的问题,有些人没有
  • 我工作站上的其他用户也有同样的问题
  • 我重新映像了我的工作站,它工作了一段时间,但随后又停止了,因为它似乎在设备安装了软件更新后停止了,所以我正在卸载这些更新,但是其中两个不会'不允许我卸载,我假设它们是由 Microsoft 强制安装并需要安装(选择时卸载按钮消失)- KB4019472 和 KB4049065。

设备运行的是 Windows 10 1607 v14393.1944、PowerShell v5.1。

我所在的域与 DC1 和 MS10 (.10) 所在的域之间存在单向信任,这些域信任我们,但我们不信任这些域。

我使用的帐户是设备上的本地管理员,通过嵌套的 AD 组,跨所有域。

我对 Kerberos 不是很了解,所以任何帮助都会很棒。

脚本如下: 注意:我不得不删除一些部分,所以我已经用那里的内容填充了该区域(即 {String} 将只有标准文本,而 {FQDNServerName} 将有一个 FQDN 服务器名称写为文本,或 {Region} 我会将区域写成文本})。

$csvSchoolsLoc = "{FQDNServerName}\SharedReports$\SchoolsExport.csv"
$Schools = Import-Csv $csvSchoolsLoc -Delimiter "`t" -Header LocCode,SchoolName,SchoolAddress,SchoolPhoneNumber,SchoolFaxNumber,SchoolOfficerInCharge,DistrictCode,DistrictNumeric,RegionCode,RegionNumeric,LSD,WANLinkType,RouterName,RouterIP,RouterStatus,OneSchemaGraphUrl,OneSchemaSiteUrl,SCCMSiteID,SiteAdminNetwork,ProxyServerIP,PrimaryDcName,PrimaryDcIP,PrimaryDcOS,PrimaryDcVersion,PrimaryDcPatch,Style

#Gets the users credentials for their GBN ZZ account - this is used throughout the script for authentication
$username = "{Region}\zz-$env:USERNAME"
$mycreds = Get-Credential -UserName $username -Message "Enter your password for {region}\zz-$env:USERNAME"

Clear-Host
Write-Host "What is the schools 4 digit site code?" -ForegroundColor Magenta
$Global:SiteCode = Read-Host

Function Main {
    Clear-Host

    $SchoolName = $schools | Where-Object {$_.LocCode -eq $SiteCode} | ForEach-Object SchoolName

    $Region = $schools | Where-Object {$_.LocCode -eq $SiteCode} | ForEach-Object RegionCode

    Write-Host "Getting details for: " -ForegroundColor Gray -NoNewline; Write-Host "$SchoolName - $SiteCode - ($Region)"-ForegroundColor Yellow

    $DC1 = "{String}$($Region)$($SiteCode)001.$region.{String}.{String}.{String}"
    $MS10 = "{String}$($Region)$($SiteCode)010.$region.{String}.{String}.{String}"

    if (Test-Connection -ComputerName $DC1 -Count 2 -Delay 1 -Quiet) {
        $DC1Run = $true
    } else {
        $DC1Run = $false
    }
    if (Test-Connection -ComputerName $MS10 -Count 2 -Delay 1 -Quiet) {
        $MS10Run = $true
    } else {
        $MS10Run = $false
    }

    $ScriptBlock = {
        $DiskCTotal = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID='C:'" -Impersonation 3 | ForEach-Object {$_.size / 1GB}
        $DiskCFree = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID='C:'" -Impersonation 3 | ForEach-Object {$_.freespace / 1GB}
        $DiskZTotal = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID='Z:'" -Impersonation 3 | ForEach-Object {$_.size / 1GB}
        $DiskZFree = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID='Z:'" -Impersonation 3 | ForEach-Object {$_.freespace / 1GB}

        return @{
            'ZFreeSpace' = $DiskZFree
            'CFreeSpace' = $DiskCFree
            'ZTotalSize' = $DiskZTotal
            'CTotalSize' = $DiskCTotal
        }
    }
    if (($DC1Run -eq $true) -and ($MS10Run -eq $true)) {
        $ServerDC1 = Invoke-Command -ComputerName $DC1 -Credential $mycreds -ScriptBlock $ScriptBlock
        $ServerMS10 = Invoke-Command -ComputerName $MS10 -Credential $mycreds -ScriptBlock $ScriptBlock

        #Clear-Host
        Write-Host -ForegroundColor Yellow "$SchoolName - $SiteCode - ($Region)"
        Write-Host -ForegroundColor Cyan "Server $DC1 - Domain Controller"
        Write-Host "$([math]::round($ServerDC1.CFreeSpace,2)) GB free on C Drive (Total Size $([math]::round($ServerDC1.CTotalSize,2)) GB)"
        Write-Host "$([math]::round($ServerDC1.ZFreeSpace,2)) GB free on Z Drive (Total Size $([math]::round($ServerDC1.ZTotalSize,2)) GB)"
        Write-Host "" 
        Write-Host -ForegroundColor Cyan "Server $MS10 - Distribution Point"
        Write-Host "$([math]::round($ServerMS10.CFreeSpace,2)) GB free on C Drive (Total Size $([math]::round($ServerMS10.CTotalSize,2)) GB)"
        Write-Host "$([math]::round($ServerMS10.ZFreeSpace,2)) GB free on Z Drive (Total Size $([math]::round($ServerMS10.ZTotalSize,2)) GB)"
    } else {
        #Clear-Host
        Write-Host -ForegroundColor Yellow "$SchoolName - $SiteCode - ($Region)"
        Write-Host -ForegroundColor Cyan "Server $DC1 - Domain Controller"
        if ($DC1Run) {
            Write-Host "DC1 connection status is running" -ForegroundColor Green
        } else {
            Write-Host "DC1 connection status is down" -ForegroundColor Red
        }
        Write-Host "" 
        Write-Host -ForegroundColor Cyan "Server $MS10 - Distribution Point"
        if ($MS10Run) {
            Write-Host "MS10 connection status is running" -ForegroundColor Green
        } else {
            Write-Host "MS10 connection status is down" -ForegroundColor Red
            if ($DC1Run -eq $true) {
                $RDP = Read-Host -Prompt "Would you like to RDP to $DC1 'Y'"
                if ($RDP -eq "Y") {
                    Start-Process -FilePath "$env:windir\System32\mstsc.exe" -ArgumentList "/v:$DC1" -Wait -WindowStyle Maximized
                }
            }
        }
    }
    Write-Host ""
    Write-Host "What is the next schools 4 digit site code? -or- Press Enter to retry the above site again" -ForegroundColor Magenta
    $Entry = Read-Host
  if ($Entry -eq "") {
    # Do nothing
  } else {
    $Global:SiteCode = $Entry
  }
}

$x = 0

do {
    Main
} until ($x -gt 0)

编辑:软件更新的卸载并没有解决问题,所以除非它与我无法卸载的那 2 个更新有关,否则它似乎不是软件更新。

【问题讨论】:

  • 有关 WinRM 配置的详细信息,请运行以下命令:winrm help config。有关详细信息,请参阅 about_Remote_Troubleshooting 帮助主题。您这样做了吗?您是否做了错误消息提示的其他任何事情?
  • @AnsgarWiechers 我做过,但我没有完全理解它,不知道我在做什么。
  • 不是真正的“解决方案”,但 Get-WMIObject cmdlet 还支持 -credentials 参数(这依赖于 RPC 而不是 WSMan)。关于您收到的错误:Invoke-Command 还支持 Authentication 参数,您可以在其中指定您希望使用的身份验证方法(我对您的环境知之甚少,不知道您是否真的需要使用 Kerberos 或其他身份验证类型)
  • 感谢@bluuf 抱歉,我应该将其添加为我尝试过的东西,但我确实尝试将身份验证类型更改为使用基本类型,但错误仍然存​​在。当我明天上班时,我会发布我得到的错误,我认为这有点不同。我相信 Get-WmiObject 确实可以工作,但是我想把它全部放在一个脚本块中,这样它就不必像我们的一些速度较慢的网站或 ADSL 链接等那样来回切换。

标签: powershell authentication invoke-command


【解决方案1】:

事实证明,我尝试访问的域不在我的 WinRM 的 TrustedHosts 配置中。

通过使用以下命令,我能够使用“*”通配符将域(我有很多域)添加到 TrustedHosts。

注意:出于保密原因,我已经用 {String} 替换了部分域,它通常包含部分域名。

winrm set winrm/config/client @{TrustedHosts="<local>,*.{string}.edu.au"}

【讨论】:

    猜你喜欢
    • 2022-12-23
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-26
    • 2016-11-01
    相关资源
    最近更新 更多