如何在Powershell上仅获得服务器的正常运行时间?



我有以下代码,当我直接在powershell中使用时,它可以工作:

Get-WmiObject win32_operatingsystem | select @{LABEL=’LastBootUpTime’;EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)

它返回:

LastBootUpTime
--------------
14/09/2019 10:41:50

但是当我在带有调用命令.ps1的 Powershell 脚本中使用该命令时,输出会返回更多信息:

LastBootUpTime        PSComputerName RunspaceId                          
--------------        -------------- ----------                          
9/14/2019 10:41:50 AM 192.168.0.20   af08d2d8-c4f1-4f85-9d6c-e3f4ffe475c6

为什么会这样?

如果可能的话,我也想没有标题LastBootUpTime。

Invoke-Command 将始终返回其他信息,在本例中为运行命令的位置和运行空间 ID。您始终可以将结果放入变量中,然后简单地打印出所需的属性。

$result = invoke-command {your-command}
$result.LastBootUpTime

或简称

(invoke-command {your-command}).LastBootupTime

注意在使用 wmi 的时候,不一定需要使用 invoke-command,也可以直接将 -computer 参数传递给它,对远程计算机运行命令:

Get-WmiObject win32_operatingsystem -computer "remote_computer_name"

由于您最终只对(转换后的(属性感兴趣,因此根本不需要使用Select-Object(其别名为select( - 改用ForEach-Object

Get-WmiObject Win32_OperatingSystem |
ForEach-Object { $_.ConvertToDateTime($_.LastBootUpTime) }

注意:您看到的额外属性(由带有-ComputerName参数的远程Invoke-Command调用添加(如下所述(在技术上仍然存在于结果中,但它们不会显示

也就是说,WMI cmdlet 在 PowerShell 版本 3 中已弃用。使用Get-CimInstance代替Get-WmiObject实际上使.ConvertToDateTime()调用变得不必要(.LastBootUpTime现在直接包含一个[datetime]实例(,在这种情况下,您可以简单地使用Select-Object-ExpandProperty参数来仅返回属性(而不是具有请求属性的[pscustomobject]实例(:

Get-CimInstance CIM_OperatingSystem | Select-Object -ExpandProperty LastBootUpTime

注意:Get-CimInstance直接支持-ComputerName参数,因此调用不需要Invoke-Command -ComputerName;与 WMI cmdlet 使用的防火墙不友好的 DCOM 协议不同,CIM cmdlet 使用与 PowerShell 远程处理相同的防火墙友好传输

或者,更简洁、更高效地使用直接属性访问,尤其是在命令仅返回单个对象的情况下:

(Get-CimInstance CIM_OperatingSystem).LastBootUpTime

这个答案对比了这两种方法的优缺点,并展示了其他替代方案。


至于你尝试过什么,通常涉及:

管理远程操作自动添加的源属性:

远程处理方案中,PowerShell 使用提供源信息的其他属性修饰返回的对象。 这些属性(大部分(属于NoteProperty类型,并添加:

  • 当涉及PowerShell 远程处理时 - 例如在你的案例中通过Invoke-Command -ComputerName

  • 当直接远程使用 CIM cmdlet(如Get-CimInstance(时,例如使用-ComputerName参数。

这些属性是:

  • .PSComputerName(执行代码的远程计算机的名称(

    • 注: 在从远程 CIM 调用返回的对象上,.PSComputerName显示为常规属性(类型Property(,而不是NoteProperty
  • 关联的隐藏.PSShowComputerName属性,默认为$true,这解释了为什么在显示输出中看到PSComputerName列。

    如果在将对象
    • 打印到屏幕之前捕获对象,则可以将属性设置为$false,在这种情况下,它们的.PSComputerName属性将不会显示(但仍会存在( - 但是,.RunspaceId属性可能 - 根据情况 -显示,并且必须显式排除 - 见下文。
  • 仅限 PowerShell 远程处理(不是远程 CIM 调用(:.RunspaceId(远程运行空间的 ID(

从对象的本地显示/状态中排除这些内容,请使用以下技术:

  • 如果只对选择属性感兴趣,请在本地进行Select-Object调用,这由于在本地构造仅具有相关属性的新[pscustomobject]实例,隐式排除远程处理添加的属性:
Invoke-Command -ComputerName ... { ... } |
Select-Object Name, LastBootUpTime  # LOCAL call to Select-Object
  • 如果对除远程处理添加的属性之外的所有属性感兴趣
    请使用Select-Object -ExcludeProperty显式消除它们:
# Get remote output, then locally exclude the remoting-added properties.
Invoke-Command -ComputerName ... { ... } |
Select-Object * -ExcludeProperty PSComputerName, PSShowComputerName, RunSpaceId

注意:Select-Object通常返回[pscustomobject]实例,这些实例的属性是输入对象的静态副本,并且缺少输入类型的方法

我找到了一种方法! 如果有人需要这里是:

Get-WmiObject win32_operatingsystem | select @{LABEL=’LastBootUpTime’;EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}|Select-Object -ExpandProperty  lastbootuptime

这是我的使用方式(我正在为我的数据库创建HTML报告(

write-output "<p> Horario do Ultimo boot: $(Get-WmiObject win32_operatingsystem | select @{LABEL=’LastBootUpTime’;EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}|Select-Object -ExpandProperty  lastbootuptime)</p>"

输出是(在我的语言和地区(:

Horario do Ultimo boot: 09/14/2019 10:41:50

最新更新