Powershell Windows Update API CopyToCache(IStringCollection)-指定的强制转换无效

Powershell Windows Update API CopyToCache(IStringCollection)-指定的强制转换无效,powershell,com,windows-update,stringcollection,Powershell,Com,Windows Update,Stringcollection,为了减少VPN路由上的流量,我需要从外部服务器下载windows更新,同时向内部服务器报告 因此,我正在做以下工作: 创建UpdateSession并搜索更新,将其存储在$SearchResult中。 然后我从外部服务器下载更新,然后我想通过 一切都很好,除了将StringCollection传递到方法CopyToCache中,结果是“指定的强制转换无效”-错误 这是我的代码: 谢谢你的帮助!埃尔多产科医院 $UpdateSession = New-Object -ComObject Micro

为了减少VPN路由上的流量,我需要从外部服务器下载windows更新,同时向内部服务器报告

因此,我正在做以下工作:

创建UpdateSession并搜索更新,将其存储在$SearchResult中。 然后我从外部服务器下载更新,然后我想通过

一切都很好,除了将StringCollection传递到方法CopyToCache中,结果是“指定的强制转换无效”-错误

这是我的代码:

谢谢你的帮助!埃尔多产科医院

$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隧道报告和搜索更新,并从外部源下载更新,我们可以在vpn隧道旁边路由流量。

您使用的是.NET对象。在注册表中搜索接口,然后查找接口的TypeLib之后,它指向wuapi.dll。然后我搜索了使用wuapi.dll作为InprocServer32的COM对象。我找到了“Microsoft.Update.StringColl.1”。它有一个
Add()
方法,因此它在代码中的工作方式应该与其他方法相同(我认为)。因此,将初始化$StringCollection的地方替换为:

$StringCollection = new-object -ComObject "Microsoft.Update.StringColl.1"

重复创建一个集合,向该集合添加一项,然后将该集合作为参数传递是没有意义的。。。
CopyToCache()
所期望的参数是什么?它可以接受普通字符串(filenmae)吗?它需要阵列吗?)<代码>$StringArray=@(((“C:\temp\WSUS\{0}”-f$FileName))在查看接口…IUpdate2::CopyToCache()后,它需要一个IStringCollection intereface…但这是一个COM接口。需要找到实现IStringCollection接口的COM对象。我认为.NET对象StringCollection并不意味着IStringCollection接口。嘿,Joseph,谢谢你的回答。我明天试试这个。向TimoHey Joseph致意,谢谢你为我的剧本提供了最后一块拼图。很好用!