远程 Powershell:Microsoft.Update.Session,访问被拒绝:0x80070005

11
我已经编写了一个脚本,使用Microsoft.Update.Session COM对象在计算机上搜索/下载/安装Windows更新。当在本地运行时它能正常工作,但是当通过远程会话或通过Invoke-Command运行时,我会收到一个0x80070005的访问被拒绝错误,该错误发生在Microsoft.Update.Session.CreateUpdateDownloader()函数中。
如果我尝试直接创建一个Downloader对象,则会收到相同的错误,代码如下:
$oUpdateDownloader = new-object -com "Microsoft.Update.Downloader" 

我是远程机器上的管理员,即使明确提供我的凭据或任何其他管理员帐户的凭据,都似乎没有改变任何内容。

我看到这个错误已经发布了很多次,但似乎没有关于解决问题的信息...

有什么想法吗?


更新的代码是什么?@klyd,你能在这里分享一下吗? - Senior Systems Engineer
7个回答

8
当你使用远程PowerShell会话时,你在远程计算机上的登录会话被标记为“网络”登录(登录类型:3)。 由于某些不明原因(安全?销售SCCM?),Windows更新代理程序COM API的部分功能仅限本地已登录管理员使用。
使用PsExec和计划任务被提出作为解决方法。
在我看来,最无缝(且仍然可靠)的解决方案是利用PowerShell的“本地虚拟帐户”功能(通过会话配置 / JEA实现)。通常,JEA用于限制用户在远程计算机上执行哪些PowerShell操作,但我们在此处(滥用)它以获得完全访问权限,就像我们是本地已登录管理员一样。
(1.)在ComputerB(远程服务器)上创建一个新的不受限制(并且持久性!)的会话配置:
New-PSSessionConfigurationFile -RunAsVirtualAccount -Path .\VirtualAccount.pssc
# Note this will restart the WinRM service:
Register-PSSessionConfiguration -Name 'VirtualAccount' [-ShowSecurityDescriptorUI] -Path .\VirtualAccount.pssc -Force
# Check the Permission property:
Get-PSSessionConfiguration -Name 'VirtualAccount'
# Those users will have full unrestricted access to the system!

(2.) 从本地客户端ComputerA连接到位于ComputerB上的无限制会话配置:

New-PSSession -ComputerName 'ComputerB' -ConfigurationName 'VirtualAccount' | Enter-PSSession
[ComputerB]: new-object -com "Microsoft.Update.Downloader" # Yay!

双跳似乎无法与JEA VirtualAccount一起使用,因此无法下载补丁。 - Dennis
这不是经典的双跳,其中您的初始连接帐户也用于连接到最终目标服务器(在此情况下为Microsoft下载或WSUS)。相反,您会模拟ComputerB上的本地虚拟帐户,因此应该显示为最终目标服务器上的计算机帐户。 - argonym

5
这是一个已知问题。似乎实际的COM对象本身存在一个bug,因为使用VBScript、PowerShell甚至C#时都会出现这个问题。有一篇很好的文章介绍了如何使用PowerShell管理Windows更新,可以在这里找到。
解决方法是在计算机上设置定期任务,然后您可以根据需要调用该任务。

我曾经认为这是一种安全“特性”,现在想知道自己是否有点太天真了! - Matt
功能 / 错误 ... 这都是相对的 :) - Andy Schneider

4

2

Windows更新代码无法从远程计算机调用。网络上有一些解决方法,包括使用psexec和脚本(PowerShell或VBScript)。

我自己使用了WUInstall,而BoeProx记录了一些替代方案,并开始了一个名为PoshPAIG的项目。我在使用之前就换了工作,所以不知道它是否有效。


1
另一种解决方案是使用PowerShell更改Windows注册表设置,并可选择重新启动wuauserv以使更改生效。

例如,在Windows Server 2008R2中,可以找到自动更新设置:

HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update

这个更改会做什么? - Dennis

0
感谢argonym和提问者:我根据argonym给出的解决方案制作了脚本,稍微修改了一下,这样我就可以从脚本文件中使用它而不是命令提示符。

$script = {
            write-host "Hello from remote target"
            #filepath is in Remote/target host
            $job = Start-job -FilePath c:\Windows_Update_2.ps1 -Verbose -Credential $cred
            echo $job
            Wait-Job $job
            $output = Receive-Job $Job
            foreach ($item in $output){
                              write-host $item
                                }
            }


$session = New-PSSession -ComputerName $computerName -Credential $cred  -ConfigurationName 'VirtualAccount' 
Invoke-Command -Session $session  -ScriptBlock $script

完整的运行示例在这里: 在GitHub上的脚本示例

虽然这个链接可能回答了问题,但最好在这里包含答案的关键部分,并提供链接作为参考。仅有链接的答案如果链接页面发生变化,就可能失效。- 来自审核 - zerocukor287

0
使用任务计划程序来解决远程 PowerShell 访问被拒绝的问题,可以使用一个脚本,该脚本使用 Microsoft.Update.Installer 对象,类似于在 GitHub 上的 windows_update_2.ps1。这可能需要超过30分钟。
# windowsUpdateRun.ps1

# windows_update_2.ps1 copied to remote machine first
# $s = new-pssession (1..3 | % tostring comp000)
# $s | % { copy windows_update_2.ps1 $home\documents -tosession $_ } 

$taskname = 'windowsUpdateRun'

$action = New-ScheduledTaskAction -Execute powershell -argument "-executionpolicy bypass $home\documents\windows_update_2.ps1 *> $home\documents\windows_update_2.log"
Register-ScheduledTask -action $action -taskname $taskname -user system -force > $null
Start-ScheduledTask -TaskName $taskname
while ((Get-ScheduledTask -TaskName $taskname).State -ne 'Ready') {
  Write-Verbose -Message 'Waiting on scheduled task...' }
Get-ScheduledTask $taskname | Get-ScheduledTaskInfo | select LastTaskResult

$s = new-pssession (1..3 | % tostring comp000)
$s | % { copy windows_update_2.ps1 $home\documents -tosession $_ } 
invoke-command $s windowsUpdateRun.ps1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接