PowerShell 技能连载 - 创建 Time Span
您可以用 New-TimeSpan
来定义时间的“量”,然后对某个日期增加或减少这个量。以下是一个例子:
1 | $1Day = New-TimeSpan -Days 1 |
更简单的办法是使用 DateTime
对象的内置方法:
1 | $today = Get-Date |
您也可以使用 TimeSpan
.NET 类来创建 time span 对象:
1 | PS C:\> [Timespan]::FromDays(1) |
您可以用 New-TimeSpan
来定义时间的“量”,然后对某个日期增加或减少这个量。以下是一个例子:
1 | $1Day = New-TimeSpan -Days 1 |
更简单的办法是使用 DateTime
对象的内置方法:
1 | $today = Get-Date |
您也可以使用 TimeSpan
.NET 类来创建 time span 对象:
1 | PS C:\> [Timespan]::FromDays(1) |
有时候,一个 PowerShell 脚本需要等待外部进程结束。以下是一些用户的做法:
1 | $processNameToWaitForExit = 'notepad' |
这种做法不太理想,因为它至少等待了一秒钟,即便进程已经不在运行了。以下是一个更好的方法:
1 | $processNameToWaitForExit = 'notepad' |
不仅代码更短,Wait-Process
也支持超时时间。如果等待的时间过长,您可以通过超时时间来结束等待。
如果您设置了 PIN 用来登录您的电脑,对您自己的机器使用 PowerShell remoting 可能会失败,提示如下奇怪的错误信息:
1 | PS C:\> Invoke-Command { "Hello" } -ComputerName $env:computername |
要解决这个问题,您可以有两个选择:
Invoke-Command
的时候使用 -Credential
参数,然后指定账户和密码。如果您使用 PowerShell 远程操作来接收远程机器的信息,您可以指定多个计算机名(扇出)。PowerShell 会自动逐台访问所有的机器,这样可以节省很多时间(当然,这些操作的前提是设置并启用了 PowerShell,这里不再赘述)。
返回的结果顺序是随机的,因为所有被访问的机器都会在它们准备好数据的时候返回各自的信息。
要将结果数据按每台机器分割,请使用 Group-Object
命令:
1 | $pc1 = $env:computername |
当您指定了 -AsHashTable
参数时,Groutp-Object
创建了一个以计算机名为键的哈希表。通过这种方法,您可以并发执行操作以节约时间,并仍然按每台机器来区分数据。
用 Group-Object
可以基于共享的属性值对对象分组,但请不要忘记使用 -NoElement
参数来忽略实际的对象而只返回出现次数。
这行简单的代码告诉您指定文件夹中有哪些文件类型:
1 | Get-ChildItem -Path c:\Windows -File | Group-Object -Property Extension -NoElement |
结果看起来如下:
1 | Count Name |
指定了 -NoElement
之后,您可以节约相当客观的内存,因为原对象不再包括在结果中。
Cmdlet 和函数只能用认可的动词以便于用户查找命令,并且保持一致性。
以下是一个快速的审计代码,能够显示不符合这个规定的所有命令:
1 | $approved = Get-Verb | Select-Object -ExpandProperty Verb |
这里返回的是所有不符合规定或根本没有命令动词的 cmdlet 和函数。
让我们来看看您的 PowerShell 中哪个命令动词是最常用的:
1 | Get-Command -CommandType cmdlet, function | |
这是我们系统的输出结果:
1 | Count Name Group |
更有趣的是,以下是 PowerShell cmdlet 前六个最常用的动词:
1 | PS C:\> Get-Command -CommandType cmdlet, function | |
所以说这头六个动词只占动词总数的 6%,但是占了所有命令的 60% 以上。
当您加密保密信息时,主要的问题是要寻找一个合适的密钥。一个特别安全的密钥是您的 Windows 身份,它和您的计算机身份绑定。这可以用来在特定的机器上加密敏感的个人信息。
以两个函数演示了如何实现:
1 | function Decrypt-Text |
您可以将密文安全地保存到文件里。只有您可以读取并解密该文件,而且只能在加密用的电脑上完成。
-WhatIf
通用参数可以打开模拟模式,这样一个 cmdlet 执行的时候并不会改变任何东西,而是汇报它“将会”改变什么。它能工作得很好, 除非开发者没有正确地实现 -WhatIf
。
有一种比较少见的情况:当您同时指定了 -Force
和 -WhatIf
参数,正确的结果是 -WhatIf
具有更高的优先级。有一些开发者过于关注 -Force
的功能,而让 -Force
优先级更高。例如请试试 Remove-SmbShare
。
在 Server 2012 R2 和 Windows .1 中,有许多有用的新模块,包含了许多新的 cmdlet,例如 New-SmbShare
可以快速地创建新的文件共享。
如果您没有这些 cmdlet,您通常可以使用 WMI。那需要更多的研究和搜索,但是一旦您有了一个代码模板,它就能很好地工作了。
例如要以管理员身份创建一个新的文件共享,试试以下代码:
1 | $share = [wmiclass]"Win32_Share" |