首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Powershell捕获调用-命令输出

Powershell捕获调用-命令输出
EN

Stack Overflow用户
提问于 2022-06-21 11:38:08
回答 2查看 353关注 0票数 2

我遇到了一个我似乎搞不懂的问题。我有一段代码,它能做我想做的事情。它搜索已安装并具有特定UpdateID的Windows更新。

代码语言:javascript
复制
param(
    $updateId = $false,
    $hostName = $false
)


if(($updateId -eq $false) -or ($hostName -eq $false))
{
   Write-Host "checkUpdateInstalled.ps1 -updateId <updateIdValue> -hostName <Remote Host Name>"
   exit
}


Invoke-Command -ComputerName $hostName -ScriptBlock {
   $searcher = New-Object -ComObject Microsoft.Update.Searcher
   $searcher.Search("IsInstalled=1 AND UpdateID='$Using:updateId'")
   $tmp.Updates| ForEach-Object {
        $i++
        Write-Host "UpdateInfo Update No. $i"
        Write-Host "Title: `t`t" $_.Title
        Write-Host "Description: `t`t " $_.Description
        Write-Host "UpdateID: `t`t " $_.Identity.UpdateID
        Write-Host "RevisionNumber: `t`t " $_.Identity.RevisionNumber
        Write-Host "KBArticleIDs: `t`t " $_.KBArticleIDs
        Write-Host "==============================================="    
    }
}

有了这个解决方案,我不能在$tmp.Updates之外使用Invoke-Command,但是我试图从ForEach-Object循环收集的信息工作得很好。在本例中,打印$tmp.Updates将为我提供有关特定更新的信息。

因此,我尝试了以下方法来访问$tmp

代码语言:javascript
复制
## Same top part


$tmp = Invoke-Command -ComputerName $hostName -ScriptBlock {
   $searcher = New-Object -ComObject Microsoft.Update.Searcher
   $searcher.Search("IsInstalled=1 AND UpdateID='$Using:updateId'")
}

$tmp.Updates| ForEach-Object {
    $i++
    Write-Host "UpdateInfo Update No. $i"
    Write-Host "Title: `t`t" $_.Title
    Write-Host "Description: `t`t " $_.Description
    Write-Host "UpdateID: `t`t " $_.Identity.UpdateID
    Write-Host "RevisionNumber: `t`t " $_.Identity.RevisionNumber
    Write-Host "KBArticleIDs: `t`t " $_.KBArticleIDs
    Write-Host "==============================================="    
}

通过这种尝试,循环不会打印信息。如果我试图打印$tmp.Updates,我只会得到System.__ComObject

有人能感觉到吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-06-21 12:53:42

这就是您将通过Invoke-Command设计得到的那种行为。

Invoke-Command不返回远程会话中的对象。相反,它返回一个对象的表示,该对象确实经历了几个过程。

首先,它在远程环境上序列化,然后在本地环境上反序列化。

这是为了所有被传播的东西。有一些按序列化方式直接反序列化为“活动”对象的原语类型,如:

  • 字节,SByte,Byte[]
  • Int16,Int32,Int64,UInt16,UInt32,Uint64
  • 十进制,单数,双
  • TimeSpan,DateTime,ProgressRecord
  • 字符串,XmlDocument,SecureString
  • 布尔值,Guid,Uri,版本

然后,您拥有的类型不是以完全的保真度反序列化,而是在大多数实际目的中作为原始类型运行。

这包括Enum,它被反序列化为基础整数。类似地,反序列化器将保留列表的内容,但可能会更改容器的实际类型。(例如:列表反序列化为ArrayList,字典反序列化为Hashtable,等等)

最后,你也有一些物体会被重新水化成他们的活的对应物。例如,IP地址对象被序列化,然后反序列化为一个Deserialized.System.Net.IPAddress,然后通过“再水合”再次转换为它的原始类型,这是一个决定如何再次转换反序列化类型的过程。

对于某些PowerShell类型的…,有一些内置的再水化。:

  • PSPrimitiveDictionary
  • SwitchParameter
  • PSListModifier
  • PSCredential

以及基类库中的某些类型:

  • IPAddress,MailAddress
  • CultureInfo
  • X509Certificate2,X500DistinguishedName
  • DirectorySecurity,FileSecurity,RegistrySecurity

因此,要完成所需的任务,需要返回可序列化的对象。您需要深入了解COM对象并返回所需的属性值。您可以使用Get-Member来确定可用的属性,然后从那里返回所需的内容。

您还可以在远程对象上使用ConvertTo-Json返回它的json表示,并在本地将其转换回PSObject。按类型划分,您也无法得到准确的表示,但您可能会更好地查看属性/值。如果需要,不要忘记将-Depth参数设置为更高的数目,因为缺省值是4层深。

参考

Microsoft blogs如何将对象发送到远程地址和从远程地址发送

票数 4
EN

Stack Overflow用户

发布于 2022-06-21 15:20:35

返回的序列化对象的深度似乎有限制(没有方法)。这对我有效,直接返回更新子属性。否则“更新”就会变成一个字符串数组。虽然我会用"get-ciminstance win32_quickfixengineering“代替。

代码语言:javascript
复制
$tmp = Invoke-Command localhost {  # elevated
  $searcher = New-Object -ComObject Microsoft.Update.Searcher
  $searcher.Search('IsInstalled=1')
}
$tmp.Updates
System.__ComObject
System.__ComObject
System.__ComObject
...


$tmp.Updates[0].gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
代码语言:javascript
复制
$tmp = Invoke-Command localhost {  # elevated
    $searcher = New-Object -ComObject Microsoft.Update.Searcher
    $searcher.Search('IsInstalled=1').updates
 }
$tmp | % title

MSXML 6.0 RTM Security Update  (925673)
Update for Microsoft Report Viewer Redistributable 2010 Service Pack 1 (KB2549864)
Security Update for Microsoft Visual C++ 2005 Service Pack 1 Redistributable Package (KB2538242)
...

归还你想要的财产..。

代码语言:javascript
复制
Invoke-Command localhost {  # elevated
  $searcher = New-Object -ComObject Microsoft.Update.Searcher
  $searcher.Search('IsInstalled=1').updates | select title, description,
    @{n='UpdateID'; e={$_.Identity.UpdateID}},
    @{n='RevisionNumber';e={$_.Identity.RevisionNumber}}, KBArticleIDs
}

Title          : Update for Windows Defender Antivirus antimalware platform - KB4052623 (Version 4.18.2001.10)
Description    : This package will update Windows Defender Antivirus antimalware platform’s components on the user machine.
UpdateID       : c01629fc-64ea-45f3-b7cb-cabc7d566933
RevisionNumber : 200
KBArticleIDs   : {4052623}
PSComputerName : localhost
RunspaceId     : 57b3ae43-6ee6-4e0c-add1-d9d82aba3f61
代码语言:javascript
复制
invoke-command localhost { get-ciminstance win32_quickfixengineering }

Source        Description      HotFixID      InstalledBy          InstalledOn                PSComputerName
------        -----------      --------      -----------          -----------                --------------
              Update           KB5013887     NT AUTHORITY\SYSTEM  6/18/2022 12:00:00 AM      localhost
              Update           KB4562830     NT AUTHORITY\SYSTEM  2/1/2021 12:00:00 AM       localhost
              Update           KB4577586     NT AUTHORITY\SYSTEM  5/24/2021 12:00:00 AM      localhost
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72700091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档