我确信这对于社区来说是一件容易的事,但它却让我感到困惑。
如果我在 PS 中创建一个变量,比如“$s”,然后将“systeminfo /s {hostname}”分配给该变量($s = systeminfo /s {hostname}
)——我如何从该变量中提取单个信息来显示?
例如:运行 cmd 填充 var 后,我只想返回系统启动时间。
$s = systeminfo /s majorsys01
"$s.System Boot Time" doesn't return anything.
那么,我该如何输出这种类型的数据呢?Get-Aduser 在这方面表现非常好,但输出中没有任何空格,而那些都是报告字段。
谢谢,戴尔
答案1
“Get-AdUser” 之所以有效,并不是因为没有空格,而是因为它检索的数据遗迹始终将字段分开——结果在内部生成为 PowerShell 对象,每个 LDAP 属性都存储在自己的字段中。(您看到的表是在输出时动态生成的;实际上并非如此存储作为内部的“字段:值”文本。)
然而,使用 'systeminfo' 时,外部 .exe 程序的输出总是被平铺成一个大字符串——PowerShell 完全不知道它有完全没有单独的字段。从中提取某些内容的唯一方法是通过字符串解析(即逐行使用正则表达式从文本墙中提取所需的数据)。
理想情况下,你应该找到一种方法没有使用任何外部程序(如“systeminfo”)——而是检索 PowerShell 本身已有的所需数据现有函数(或者如果有必要,调用 Windows API)。
例如,如果它是通过 WMI 可用的,那么您可以使用Get-WmiObject
(较新版本使用Get-CimInstance
)直接执行 WMI 查询,您将获得一个保留其单独属性的对象。
正如 Keith 的评论所说,“systeminfo”检索到的大多数基本数据确实可以通过 WMI/CIM 获得,因此您应该从调用 Get-CimInstance 开始:
$s = gcim -ComputerName majorsys01 Win32_OperatingSystem
$s | get-member -membertype property
$s | fl *
$s.LastBootupTime
如果没有内置 cmdlet,下一步就是寻找 .NET(C#)函数(所有这些函数都可以直接从 PowerShell 访问),或者本机 Windows API 函数(也可以从 .NET 访问,但需要多花点功夫)– 对于大多数任务,可能有人已经在 PSGallery 中为其编写了一个模块。
如果调用外部程序是唯一的方法,那么看看是否可以告诉它输出数据机器可读格式如 JSON、XML 或 CSV。例如,“systeminfo”支持以下/fo csv
选项,该选项以 PowerShell 可以解析的标准格式提供相同的字段:
$text = systeminfo /fo csv
$obj = ConvertFrom-Csv $text
$obj | get-member
$obj."System Model"
作为最后的手段,如果数据既不能通过更直接的方式(WMI 或其他 API)获得,也不能以标准格式(JSON 或 CSV)获得,则可以使用字符串解析(例如-匹配) 尝试从程序的输出中提取必要的位。