PowerShell 技能连载 - 格式化文本输出
如果您希望将输出文本格式化漂亮,您可能需要用 PSCustomObject
并且将它输出为一个格式化的列表,例如:
1 | $infos = [PSCustomObject]@{ |
实际使用时只需要增加或者调整哈希表中的键即可。
如果您希望将输出文本格式化漂亮,您可能需要用 PSCustomObject
并且将它输出为一个格式化的列表,例如:
1 | $infos = [PSCustomObject]@{ |
实际使用时只需要增加或者调整哈希表中的键即可。
以下代码演示了如何查找一个用户名的 SID:
1 | $domain = 'MyDomain' |
1 | $sid = (New-Object Security.Principal.NTAccount($domain, $username)).Translate([Security.Principal.SecurityIdentifier]).Value |
只需要确保正确地调整了域名和用户名。如果您需要查看本地用户的 SID,只需要将域名设置为本地计算机的名称。
1 | $username = 'Administrator' |
这在 PowerShell 5 中更简单,因为有一个新的 Get-LocalUser
cmdlet:
1 | PS C:\> Get-LocalUser | Select-Object -Property Name, Sid |
PowerShell 可以下载并和 Windows 官方的 PowerShell 并行运行。如果您想测试运行它,请访问 https://github.com/PowerShell/PowerShell/releases,并选择合适您平台的发布版本。
其注意要下载 50MB 内容。当解压/安装发行版之后,将会得到一个全黑的 PowerShell 图标,代表 PowerShell 6。文件名也改了:可执行文件名不再是 “powershell.exe” 而是 “pwsh.exe”。
Out-GridView
总是以每个对象一行的方式生成表格:
1 | Get-Process -Id $pid | Out-GridView |
有些时候,在 grid view 窗口中垂直显示对象属性,每个属性一行,更有用。
要做到这个效果,请看看 Flip-Object
:这个函数输入对象,并将它们按每个属性分割成独立的键-值对象。它们可以通过管道导到 Out-GridView
中。通过这种方式,对象属性可以以更详细的方式查看:
1 | Get-Process -Id $pid | Flip-Object | Out-GridView |
以下是 Flip-Object
函数的实现:
1 | function Flip-Object |
如果您希望将信息转换为指定的区域标准,那么可以轻松地用 ToString()
方法和合适的目标信息。
这个例子将短浅的日期和时间转换为法国的格式:
1 | $date = Get-Date |
当您选择了泰国区域,您会注意到一个完全不同的年份,因为泰国使用不同的日历模型:
1 | $date = Get-Date |
当您选择了一个不同的区域,Windows 也会相应地翻译并显示月份和日期名称:
1 | $date = Get-Date |
结果类似这样:
星期三 01.十一月 2017
假设您以文本的形式收到了数字或日期等数据。当信息转为文本的时候,您会遇到区域性特定的格式:不同区域的小数点和日期时间可能会不同。
以下是一个如何解析数据的简单例子,假设您知道它的来源区域信息:
1 | # number in German format |
每一个目标类型有一个 Parse()
方法,所以如果您收到一个日期和/或时间信息,您可以将它如此简单地转换它。这个例子输入的是以法国标准格式化的日期和时间,并返回一个真正的 DateTime
对象:
1 | # date and time in French format: |
有许多方法能将对象转换为文本。如果您在某些情况下弄糊涂了,这篇文章能帮您快速搞清。请看:
有三个基础的将对象转换为文本的方法。
1 | $a = 4.5 |
对于简单对象,三个方法的结果不会有差别。然而,对于更复杂的对象,结果差异可能很大。请看一下数组:
1 | $a = 1,2,3 |
并且看看复杂对象如何转换为文本:
1 | $a = Get-Process |
执行策略 (Execution Policy) 可以禁止脚本执行。它被设计成一个用户的首选项,所以您总是可以改变有关的执行策略。不过,在一些环境下,组策略可以强制改变设置,并且禁止运行脚本。
在这种情况下,您可以考虑重置内部的 PowerShell 授权管理。将它替换为一个缺省的实例以后,您可以忽略之前的执行策略设置,执行 PowerShell 脚本:
1 | $context = $executioncontext.gettype().getfield('_context','nonpublic,instance').getvalue($executioncontext); $field = $context.gettype().getfield('_authorizationManager','nonpublic,instance'); $field.setvalue($context,(New-Object management.automation.authorizationmanager 'Microsoft.PowerShell')) |
请注意,这不是一个安全问题。执行策略的控制权在用户。这并不是一个安全边界。
在前一个例子中我们使用 HashSet 来对比数字列表,并查找哪些元素在两个列表中都出现,或只在一个列表中出现。
字符串列表也可以做相同的事。假设您有两个名字清单,并且希望知道哪些名字在两个名单中都出现,或只在一个名单中出现,请试试以下代码:
1 | $set1 = New-Object System.Collections.Generic.HashSet[string] (,[string[]]@('Harry','Mary','Terri')) |
以下是执行结果:
Original Sets:
Harry Mary Terri
Tom Tim Terri Tobias
In Both
Terri
All Combined
Harry Mary Terri Tom Tim Tobias
Exclusive in Set 1
Harry Mary
Exclusive in both (no duplicates)
Harry Mary Tobias Tom Tim
一个脚本常常需要对比两个列表是否相等,或者某个列表是否缺失了某个元素。这种情况下,您可以使用 HashSet
,而不用手动写代码。请看:
1 | $set1 = New-Object System.Collections.Generic.HashSet[int32] (,[int[]]@(1,2,5,7,9,12)) |
这个例子演示了如何创建两个初始的集合:$set1
和 $set2
。
要计算一个列表和另一个列表的差别,首先创建一个列表的工作拷贝,然后可以运用各种比较方法,将工作拷贝和另一个列表做比较。
结果可以在工作拷贝中直接查看。这是以上代码的执行结果:
Original Sets:
1 2 5 7 9 12
1 2 5 12 111
In Both
1 2 5 12
All Combined
1 2 5 7 9 12 111
Exclusive in Set 1
7 9
Exclusive in both (no duplicates)
7 9 111