当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 使用 PowerShell 转换词汇时间跨度

作者:精品下载站 日期:2024-12-14 07:56:39 浏览:14 分类:玩电脑

使用 PowerShell 转换词汇时间跨度


我一直在从事一些脚本项目,我正在处理的数据包含词汇时间跨度。说什么?这些东西你可能都见过。这是一个类似于 P0DT0H0M47S 的字符串,表示时间跨度。它们对于人类来说并不难阅读。这个说“0 天 0 小时 0 分 47 秒”。该格式是时间跨度或持续时间在 XML 文件中的存储方式。您可以在 https://www.w3.org/TR/xmlschema-2/#duration 阅读更多相关信息。但我希望将这些价值视为更适合 PowerShell 的时间跨度。事实证明,这实际上非常简单。

您可以在 Windows 中的计划任务中看到这些值。

[玩转系统] 使用 PowerShell 转换词汇时间跨度

我知道PT72H代表72小时的时间跨度。将其转换为时间跨度对象很简单。一旦你知道如何做,很快你就会知道。您可以使用内置的 XML 方法来转换该值。

[System.Xml.XmlConvert]::ToTimeSpan("PT72H")

[玩转系统] 使用 PowerShell 转换词汇时间跨度

果然,这就是72小时,也就是3天。如果以另一种方式转换呢?

$ts = New-TimeSpan -hours 72
[System.Xml.XmlConvert]::ToString($ts)

[玩转系统] 使用 PowerShell 转换词汇时间跨度

诚然,该字符串有所不同,但它仍然代表 72 小时。

过程很简单,但我仍然编写了一对 PowerShell 高级函数来处理这些任务。

Function ConvertTo-LexicalTimespan {
    [cmdletbinding()]
    [OutputType("String")]
    Param(
        [Parameter(Position = 0, Mandatory,HelpMessage = "Enter a timespan object", ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [timespan]$Timespan
    )
    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)"

    } #begin

    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Converting $Timespan"
        Try {
            [System.Xml.XmlConvert]::ToString($Timespan)
        }
        Catch {
            Throw $_
        }
    } #process

    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)"
    } #end

} #close ConvertTo-LexicalTimespan

Function ConvertFrom-LexicalTimespan {
    [cmdletbinding()]
    [OutputType("string", "timespan")]
    Param(
        [Parameter(Position = 0, Mandatory, HelpMessage = "Enter a lexical time string like P23DT3H43M. This is case-sensitive.", ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$String,
        [Parameter(HelpMessage = "Format the timespan as a string")]
        [switch]$AsString
    )
    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)"
    } #begin

    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Converting $($String.toUpper()) to a timespan"
        Try {
            #convert string to upper case to help the user out
            $r = [System.Xml.XmlConvert]::ToTimeSpan($String.ToUpper())
            if ($AsString) {
                Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Displaying as a timespan string"
                $r.toString()
            }
            else {
                $r
            }
        }
        Catch {
            Throw $_
        }
    } #process

    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)"
    } #end

} #close ConvertFrom-LexicalTimespan

让我们看看它们是如何工作的。

这是另一个原始示例。

[玩转系统] 使用 PowerShell 转换词汇时间跨度

或者我可以使用这样的代码:

(get-scheduledtask dailywatcher).settings.idlesettings | 
select-object @{Name="Idle";Expression={ConvertFrom-LexicalTimespan $_.idleDuration}},
@{Name="Wait";Expression={ConvertFrom-LexicalTimespan $_.WaitTimeout}}

[玩转系统] 使用 PowerShell 转换词汇时间跨度

现在,我有了更有意义的输出。

这是使用 Get-WsManInstance 显示连接的 psessions 的最后一个示例。

[玩转系统] 使用 PowerShell 转换词汇时间跨度

但我想您会同意使用此代码会产生更好的结果。

Get-WSManInstance -ComputerName DOM1 -ResourceURI Shell -Enumerate | 
 Select-Object -Property ResourceURI,Owner,ClientIP,
 @{Name="ShellRunTime";Expression = {ConvertFrom-LexicalTimespan $_.ShellRunTime}},
 @{Name="ShellInactivity";Expression = {ConvertFrom-LexicalTimespan $_.ShellInactivity}},
 @{Name="IdleTimeOut";Expression = {ConvertFrom-LexicalTimespan $_.IdleTimeOut}},
 @{Name="MaxIdleTimeOut";Expression = {ConvertFrom-LexicalTimespan $_.MaxIdleTimeOut}},
 @{Name="Computername";Expression={"DOM1"}}

[玩转系统] 使用 PowerShell 转换词汇时间跨度

这是我将放入函数中的代码,用于为 PowerShell 管道创建有意义的输出。或者,如果我想要更具交互性的东西,我可以使用 PSTypeExtensionTools 模块并创建扩展。

$t = "System.Xml.XmlElement#http://schemas.microsoft.com/wbem/wsman/1/windows/shell#Shell"
$t | Add-PSTypeExtension -MemberType ScriptProperty -MemberName ShellRun -Value {[System.Xml.XmlConvert]::ToTimeSpan($this.ShellRunTime) }
$t | Add-PSTypeExtension -MemberType ScriptProperty -MemberName ShellInactive -Value {[System.Xml.XmlConvert]::ToTimeSpan($this.ShellInactivity) }
$t | Add-PSTypeExtension -MemberType ScriptProperty -MemberName Idle -Value {[System.Xml.XmlConvert]::ToTimeSpan($this.IdleTimeout) }
$t | Add-PSTypeExtension -MemberType ScriptProperty -MemberName MaxIdle -Value {[System.Xml.XmlConvert]::ToTimeSpan($this.MaxIdleTimeout) }

这使得运行命令和选择新属性变得更加容易。

[玩转系统] 使用 PowerShell 转换词汇时间跨度

或者我可以创建自定义格式视图。但我会把这个练习留给你。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯