PowerShell 技能连载 - 查找不合规的命令动词
Cmdlet 和函数只能用认可的动词以便于用户查找命令,并且保持一致性。
以下是一个快速的审计代码,能够显示不符合这个规定的所有命令:
1 | $approved = Get-Verb | Select-Object -ExpandProperty Verb |
这里返回的是所有不符合规定或根本没有命令动词的 cmdlet 和函数。
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" |
昨天我们看了自定义作用域能够自动还原变量并在您的代码之后清除现场。
自定义作用域也可以用来忽略域里任何一段代码输出的任何结果。要实现它,请使用这样的解构:$null = .{[code]}
。无论您在方括号里执行什么代码,您创建的所有的变量和函数在域外都能使用,但是不会产生任何输出。
让我们看看这个函数:
1 | function Out-Voice ($Text) |
当你运行它时,它将能播放语音,但也输出了数字“1”。所以 Speak()
方法会造成这样的现象——当您的代码变得庞大而复杂时,有许多地方在输出不必要的数字。
以下是一个极简单的“补丁”函数能产生相同的小郭,但是保证不会返回任何值:
1 | function Out-Voice ($Text) |
当您改变变量时,您可能需要在稍后清除它们并且确保它们回退到缺省值——用自定义作用域就可以做到。昨天,我们学习了如何处理控制台程序的错误。并且回顾那段代码,您会发现重置 $ErrorActionPreference
系统变量要费很多事:
1 | try |
一个简单得多的办法是使用自定义作用域:
1 | & { |
${[code]}
这段代码创建了一个新的作用域,并且任何在其中定义的变量都会在退出该作用域时删除。这是为何在上述例子中,$ErrorActionPreference
能够自动还原为它之前的值。
是否想知道如何捕获 native 控制台 EXE 程序的错误?PowerShell 的错误处理器只能处理 .NET 代码的错误。
这段代码是捕获控制台应用程序错误的框架:
1 | try |
一旦控制台程序发出一个错误,它就会输出到控制台的 #2 通道。由于示例代码中该通道直接重定向到普通的 output,所以 PowerShell 能接收到它。当 ErrorActionPreference
设成 “Stop
“ 时,PowerShell 会将任何该通道的输入数据转发到一个 .NET RemoteException
,这样您就可以捕获它。
1 | WARNING: The user name could not be found. |
在处理错误时,您有时会希望将原始的异常替换成您自己的。以下是一个例子:
1 | function Do-Something |
调用者看到的内容如下:
1 | PS C:\> Do-Something |
如果调用者也用一个错误处理函数来接收它,则会出现这种情况:
1 | try |
结果看起来如下:
1 | Message Originalmessage |
这样调用者可以看到返回的错误信息,并且经过内部处理之后,还可以传递原始的错误信息。
假设您想以不同的身份打开多个 PowerShell 控制台,或以其他人的身份打开任何程序。
要实现这个目标,您需要以其他人的身份登录,这很明显是个负担。以下是将凭据以安全的方式保存到文件的方法:密码采用您的身份和您的机器加密成密文。只有保存它们的那个人可以取回它,而且只能在保存该文件的机器上操作:
1 | # saving credential securely to file |
这个凭据将保存到用户配置中。如果您希望保存到其它地方,请改变路径。喜欢保存多少份,就调用多少次该方法。
下一步,假设您加载了一个保存的凭据,并且使用该身份启动了一个程序:
1 | # getting back saved credential |
这将以您之前指定的用户身份创建一个新的 PowerShell 实例——无需手动登录。