Windows 更新 API CopyToCache(IStringCollection) - 指定的转换无效
Windows Update API CopyToCache(IStringCollection) - Specified cast is not valid
为了减少我们 VPN 路由上的流量,我需要在向我们的内部服务器报告时从外部服务器下载 windows 更新。
所以我正在做以下事情:
创建一个 UpdateSession 并搜索更新,将它们存储在 $SearchResult 中。
然后我从外部服务器下载更新,然后我想通过 IUpdate2.CopyToCache(IStringCollection)
将它们传递到 Windows 更新 Api
一切都很好,除了将 StringCollection 传递到方法 CopyToCache 中,它只是以 'Specified cast is not valid.'-Error 结束。
这是我的代码:
感谢您的帮助! eldo-ob
$UpdateSession = New-Object -ComObject Microsoft.Update.Session
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
$UpdateCollection = New-Object -Com Microsoft.Update.UpdateColl
$SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Software'")
$AvailibleUpdates = [int16]$SearchResult.Updates.Count
$AvailibleUpdates
$WebClient = New-Object System.Net.WebClient
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
@($SearchResult.Updates.Item(0).BundledUpdates) | Foreach {
$_.DownloadContents | Foreach {
$FileName = $_.DownloadUrl.Split("/")[-1]
$downloadFrom = $_.DownloadUrl.Replace("http://contoso-intern.com","https://contoso-extern.com")
$WebClient.DownloadFile($downloadFrom,("C:\temp\WSUS\{0}" -f $FileName))
Write-Host "File Downloaded" -ForegroundColor Green
}
$StringCollection = New-Object System.Collections.Specialized.StringCollection
$StringCollection.Add(("C:\temp\WSUS\{0}" -f $FileName))
$_.CopyToCache($StringCollection)
}
错误信息:
Specified cast is not valid.
At line:24 char:19
+ $_.CopyToCache($StringCollection)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], InvalidCastException
+ FullyQualifiedErrorId : System.InvalidCastException
更新/解决方案:
# create UpdateSession
$UpdateSession = New-Object -ComObject Microsoft.Update.Session
# create UpdateSearcher
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
# search for updates & count updates
$SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Software'")
$AvailibleUpdates = [int16]$SearchResult.Updates.Count
# create an WebClient instance for downloading Updates from alternative source
$WebClient = New-Object System.Net.WebClient
# fix some tls issues (not for everyone neccessary)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# iterate the updates in searchresult
$SearchResult.Updates | ForEach-Object {
# iterate bundledupdates
$_.BundledUpdates | ForEach-Object {
# create COM stringcollection
$StringCollection = New-Object -ComObject "Microsoft.Update.StringColl.1"
# iterate downloadcontents
$_.DownloadContents | ForEach-Object {
# get the filename from url
$FileName = $_.DownloadUrl.Split("/")[-1]
# create external downloadlink
$downloadFrom = $_.DownloadUrl.Replace("http://contoso-intern.com","https://contoso-extern.com/wsusreplica")
# download update with webclient
$WebClient.DownloadFile($downloadFrom,("C:\temp\WSUS\{0}" -f $FileName))
# adding downloaded filepath to stringcollection
$StringCollection.Add(("C:\temp\WSUS\{0}" -f $FileName))
}
# copy downloaded file to cache (load into wuapi)
$_.CopyToCache($StringCollection)
}
}
# create installer
$Installer = $UpdateSession.CreateUpdateInstaller()
# set the updates
$Installer.Updates = $SearchResult.Updates
# and install
$Installer.Install()
无需使用来自自选位置的 UpdateDownloader 即可成功安装的更新。所以现在我可以通过 vpn-tunnel 报告和搜索更新,并从外部源下载更新,我们可以在 vpn 隧道旁边路由流量。
您正在使用 .NET 对象。在注册表中搜索接口后,然后查找接口的 TypeLib,它指向 wuapi.dll。然后,我搜索了使用 wuapi.dll 作为其 InprocServer32 的 COM 对象。我找到了“Microsoft.Update.StringColl.1”。它有一个 Add()
方法,因此它在代码中的工作方式应该与您的其他方法相同(我认为)。所以,用这个替换你初始化 $StringCollection 的地方:
$StringCollection = new-object -ComObject "Microsoft.Update.StringColl.1"
为了减少我们 VPN 路由上的流量,我需要在向我们的内部服务器报告时从外部服务器下载 windows 更新。
所以我正在做以下事情:
创建一个 UpdateSession 并搜索更新,将它们存储在 $SearchResult 中。 然后我从外部服务器下载更新,然后我想通过 IUpdate2.CopyToCache(IStringCollection)
将它们传递到 Windows 更新 Api一切都很好,除了将 StringCollection 传递到方法 CopyToCache 中,它只是以 'Specified cast is not valid.'-Error 结束。
这是我的代码:
感谢您的帮助! eldo-ob
$UpdateSession = New-Object -ComObject Microsoft.Update.Session
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
$UpdateCollection = New-Object -Com Microsoft.Update.UpdateColl
$SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Software'")
$AvailibleUpdates = [int16]$SearchResult.Updates.Count
$AvailibleUpdates
$WebClient = New-Object System.Net.WebClient
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
@($SearchResult.Updates.Item(0).BundledUpdates) | Foreach {
$_.DownloadContents | Foreach {
$FileName = $_.DownloadUrl.Split("/")[-1]
$downloadFrom = $_.DownloadUrl.Replace("http://contoso-intern.com","https://contoso-extern.com")
$WebClient.DownloadFile($downloadFrom,("C:\temp\WSUS\{0}" -f $FileName))
Write-Host "File Downloaded" -ForegroundColor Green
}
$StringCollection = New-Object System.Collections.Specialized.StringCollection
$StringCollection.Add(("C:\temp\WSUS\{0}" -f $FileName))
$_.CopyToCache($StringCollection)
}
错误信息:
Specified cast is not valid.
At line:24 char:19
+ $_.CopyToCache($StringCollection)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], InvalidCastException
+ FullyQualifiedErrorId : System.InvalidCastException
更新/解决方案:
# create UpdateSession
$UpdateSession = New-Object -ComObject Microsoft.Update.Session
# create UpdateSearcher
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
# search for updates & count updates
$SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Software'")
$AvailibleUpdates = [int16]$SearchResult.Updates.Count
# create an WebClient instance for downloading Updates from alternative source
$WebClient = New-Object System.Net.WebClient
# fix some tls issues (not for everyone neccessary)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# iterate the updates in searchresult
$SearchResult.Updates | ForEach-Object {
# iterate bundledupdates
$_.BundledUpdates | ForEach-Object {
# create COM stringcollection
$StringCollection = New-Object -ComObject "Microsoft.Update.StringColl.1"
# iterate downloadcontents
$_.DownloadContents | ForEach-Object {
# get the filename from url
$FileName = $_.DownloadUrl.Split("/")[-1]
# create external downloadlink
$downloadFrom = $_.DownloadUrl.Replace("http://contoso-intern.com","https://contoso-extern.com/wsusreplica")
# download update with webclient
$WebClient.DownloadFile($downloadFrom,("C:\temp\WSUS\{0}" -f $FileName))
# adding downloaded filepath to stringcollection
$StringCollection.Add(("C:\temp\WSUS\{0}" -f $FileName))
}
# copy downloaded file to cache (load into wuapi)
$_.CopyToCache($StringCollection)
}
}
# create installer
$Installer = $UpdateSession.CreateUpdateInstaller()
# set the updates
$Installer.Updates = $SearchResult.Updates
# and install
$Installer.Install()
无需使用来自自选位置的 UpdateDownloader 即可成功安装的更新。所以现在我可以通过 vpn-tunnel 报告和搜索更新,并从外部源下载更新,我们可以在 vpn 隧道旁边路由流量。
您正在使用 .NET 对象。在注册表中搜索接口后,然后查找接口的 TypeLib,它指向 wuapi.dll。然后,我搜索了使用 wuapi.dll 作为其 InprocServer32 的 COM 对象。我找到了“Microsoft.Update.StringColl.1”。它有一个 Add()
方法,因此它在代码中的工作方式应该与您的其他方法相同(我认为)。所以,用这个替换你初始化 $StringCollection 的地方:
$StringCollection = new-object -ComObject "Microsoft.Update.StringColl.1"