通过Powershell从WSUS API获取更新的CVE ID属性

时间:2010-04-01 14:54:31

标签: windows security api powershell

我正在Powershell中编写一个脚本,以从每台计算机获取更新信息,并将信息与另一个通过CVE ID识别更新的系统相关联。我发现在WSUS中有一个“CVEIDs”属性用于更新,这在MSDN中有记录,但我不知道如何访问该属性。从WSUS中检索CVE ID是这个脚本的关键,所以我希望有人可以提供帮助!

以下是我无法访问的属性:

IUpdate2 :: CveIDs属性 - http://msdn.microsoft.com/en-us/library/aa386102(VS.85).aspx

根据这个,接口IUpdate2需要IUnknown :: QueryInterface方法 - “http://msdn.microsoft.com/en-us/library/ee917057(PROT.10).aspx

“可以通过调用IUpdateCollection :: Item(opnum 8)(第3.22.4.1节)方法来检索IUpdate实例。

客户端可以使用IUnknown :: QueryInterface方法获取IUpdate2,IUpdate3,IUpdate4或IUpdate5接口。此外,如果更新是驱动程序,则客户端可以使用IUnknown :: QueryInterface方法获取IWindowsDriverUpdate,IWindowsDriverUpdate2,IWindowsDriverUpdate3,IWindowsDriverUpdate4或IWindowsDriverUpdate5接口。 “

这是我的代码的骨架:

[System.Reflection.Assembly] :: LoadWithPartialName(“Microsoft.UpdateServices.Administration”)|出空

if(!$ wsus) {

返回实现IUpdateServer

的对象

$ wsus = [Microsoft.UpdateServices.Administration.AdminProxy] :: GetUpdateServer($ server,$ false,$ port) }

$ computerScope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope $ updateScope = New-Object Microsoft.UpdateServices.Administration.UpdateScope $ updateScope.UpdateSources = [Microsoft.UpdateServices.Administration.UpdateSources] :: MicrosoftUpdate $ wsusMachines = $ wsus.GetComputerTargets($ computerScope)

QSUS中的foreach机器,写出完整的域名

$ wsusMachines | ForEach-Object { 写主机$ .FullDomainName $ updates = $ .GetUpdateInstallationInfoPerUpdate($ updateScope)

每台机器的foreach更新,写入更新标题,安装状态和securitybulletin

$ updates | ForEach-Object { $ update = $ wsus.GetUpdate($ .UpdateId)#返回实现Microsoft.UpdateServices.Administration.IUpdate的对象 $ updateTitle = $ update.Title |写主机 $ updateInstallationState = $ .UpdateInstallationState |写主机 $ updateSecurityBulletin = $ update.SecurityBulletins |写主机 $ updateCveIds = $ update.CveIDs #ERROR:属性'CveIDs'属于IUpdate2,不属于IUpdate } }

2 个答案:

答案 0 :(得分:0)

我不熟悉此API,但在COM查询界面的情况下,请尝试使用PowerShell中的强制转换来检索实现IUpdate的对象:

[Microsoft.UpdateServices.Administration.IUpdate2]$wsus.GetUpdate($.UpdateId)

答案 1 :(得分:0)

您可以尝试使用我的get-interface脚本,它可能会工作,但我猜它不会像powershell munges和特殊情况的COM对象。您的里程可能会有所不同:

function Get-Interface {

#.Synopsis
#   Allows PowerShell to call specific interface implementations on any .NET object. 
#.Description
#   Allows PowerShell to call specific interface implementations on any .NET object. 
#
#   As of v2.0, PowerShell cannot cast .NET instances to a particular interface. This makes it
#   impossible (shy of reflection) to call methods on explicitly implemented interfaces.   
#.Parameter Object
#   An instance of a .NET class from which you want to get a reference to a particular interface it defines.
#.Parameter InterfaceType
#   An interface type, e.g. [idisposable], implemented by the target object.
#.Example
#   // a class with explicitly implemented interface   
#   public class MyObj : IDisposable {
#      void IDisposable.Dispose()
#   }
#   
#   ps> $o = new-object MyObj
#   ps> $i = get-interface $o ([idisposable])
#   ps> $i.Dispose()      
#.ReturnValue
#   A PSCustomObject with ScriptMethods and ScriptProperties representing methods and properties on the target interface.
#.Notes
# AUTHOR:    Oisin Grehan http://www.nivot.org/
# LASTEDIT:  2009-03-28 18:37:23
# REVISION:  0.2

    [CmdletBinding()]
    param(
        [parameter(valuefrompipeline=$true, position=0)]
        [ValidateNotNull()]
        $Object,

        [parameter(position=1)]            
        [ValidateScript( { $_.IsInterface } )]
        [type]$InterfaceType
    )

    $script:t  = $Object.GetType()

    try {

        $script:m  = $t.GetInterfaceMap($InterfaceType)

    } catch [argumentexception] {

        throw "Interface $($InterfaceType.Name) not found on ${t}!"
    }

    $script:im = $m.InterfaceMethods
    $script:tm = $m.TargetMethods

    # TODO: use param blocks in functions instead of $args
    #       so method signatures are visible via get-member

    $body = {
         param($o, $i) 

         $script:t  = $o.GetType()
         $script:m  = $t.GetInterfaceMap($i)
         $script:im = $m.InterfaceMethods
         $script:tm = $m.TargetMethods

         for ($ix = 0; $ix -lt $im.Count; $ix++) {

            $mb = $im[$ix]

            # for the function body, we close over $ix to capture the index
            # so even on the next iteration of this loop, the $ix value will
            # be frozen within the function's scriptblock body
            set-item -path function:script:$($mb.Name) -value {

                # call corresponding target method
                $tm[$ix].Invoke($o, $args)

            }.GetNewClosure() -verbose -force

            if (!$mb.IsSpecialName) {
                # only export the function if it is not a getter or setter.
                Export-ModuleMember $mb.Name -verbose
            }
         }
    }

    write-verbose $body.tostring()    

    # create dynamic module
    $module = new-module -ScriptBlock $body -Args $Object, $InterfaceType -Verbose

    # generate method proxies - all exported members become scriptmethods
    # however, we are careful not to export getters and setters.
    $custom = $module.AsCustomObject()

    # add property proxies - need to use scriptproperties here.
    # modules cannot expose true properties, only variables and 
    # we cannot intercept variables get/set.

    $InterfaceType.GetProperties() | % {

        $propName = $_.Name
        $getter   = $null
        $setter   = $null

        if ($_.CanRead) {

            # where is the getter methodinfo on the interface map?
            $ix = [array]::indexof($im, $_.GetGetMethod())

            # bind the getter scriptblock to our module's scope
            # and generate script to call target method
            #
            # NOTE: we cannot use a closure here because sessionstate
            #       is rebound to the module's, and $ix would be lost
            $getter = $module.NewBoundScriptBlock(
                [scriptblock]::create("`$tm[{0}].Invoke(`$o, @())" -f $ix))
        }

        if ($_.CanWrite) {

            # where is the setter methodinfo on the interface map?
            $ix = [array]::indexof($im, $_.GetSetMethod())

            # bind the setter scriptblock to our module's scope
            # and generate script to call target method
            #
            # NOTE: we cannot use a closure here because sessionstate
            #       is rebound to the module's, and $ix would be lost
            $setter = $module.NewBoundScriptBlock(
                [scriptblock]::create(
                    "param(`$value); `$tm[{0}].Invoke(`$o, `$value)" -f $ix))
        }

        # add our property to the pscustomobject
        $prop = new-object management.automation.psscriptproperty $propName, $getter, $setter
        $custom.psobject.properties.add($prop)
    }

    # insert the interface name at the head of the typename chain (for get-member info)
    $custom.psobject.TypeNames.Insert(0, $InterfaceType.FullName)

    # dump our pscustomobject to pipeline
    $custom
}