PowerShell 技能连载 - 检查(本地和远程的)硬盘容量
WMI 可以提供硬盘的容量和剩余空间。PowerShell 会用返回这样的友好信息:
1 | PS C:\> # local |
以下是代码:
1 | function Get-HardDriveSize |
WMI 可以提供硬盘的容量和剩余空间。PowerShell 会用返回这样的友好信息:
1 | PS C:\> # local |
以下是代码:
1 | function Get-HardDriveSize |
支持 PowerShell 2 以上版本
许多早先基于 DCOM 的命令需要打开“远程管理防火墙例外”,才能访问远程系统。其中包含 Get-WmiObject
等 Cmdlet。
一个启用该功能的简单办法是在管理员权限下运行以下命令:
1 | netsh firewall set service remoteadmin enable |
虽然该命令已经准备淘汰,不过它仍然能用,而且是配置防火墙的最简单方法。
支持 PowerShell 3 以上版本
If you’d like to know which programs start automatically on your machine, WMI may help:
如果您想了解有多少个程序随着您的机器自动启动,WMI 也许能帮上忙:
1 | PS C:\> Get-CimInstance -ClassName Win32_StartupCommand | Select-Object -Property Name, Location, User, Command, Description |
支持 PowerShell 2 以上版本
当读取 CSV 数据的时候,可能会希望重命名 CSV 的列名,以下是一个简单的实现:只需要一行一行地读取文本,并跳过第一行(第一行包括 CSV 的列名)。然后,将表头替换成一个自定义的列名:
1 | $header = ‘NewHeader1’, 'NewHeader2', 'NewHeader3' |
在前一个技能里我们演示了 Convert-Umlaut
如何转换一个字符串中的特殊字符。这在一个函数接受管道输入的时候更有用。让我们来看看增加这种特性所需要做的改变。
在不支持管道的情况下,该函数大概长这个样子:
1 | #requires -Version 3 |
可以通过这种方式执行:
1 | PS C:\> Convert-Umlaut -Text "Mößler, Christiansön" |
然而,它不能像这样执行:
1 | PS C:\> "Mößler, Christiansön" | Convert-Umlaut |
要增加管道功能,需要做两件事:
process
“ 代码块中。以下是改变后的代码:
1 | #requires -Version 3 |
现在,也可以通过管道传输数据了:
1 | PS C:\> "Mößler, Christiansön" | Convert-Umlaut |
支持 PowerShell 2.0 以上版本
有些时候我们需要将一些字符替换,例如德语的 “Umlauts”,来适应用户名或邮箱地址。
以下是一个演示如何实现这个功能的小函数:
1 | #requires -Version 3 |
要转换一个字符串,请这样使用:
1 | PS C:\> Convert-Umlaut -Text "Mößler, Christiansön" |
支持 PowerShell 2.0 以上版本
Robocopy 是一个用于拷贝文件的工具,它在 PowerShell 里的功能也是一样。然而您可以用 PowerShell 将 robocopy 封装在一个对用户友好的 PowerShell 函数中。通过这种方式,您不再需要记忆 robocopy 别扭的命令行选项。取而代之的是 PowerShell 参数和智能提示功能。
一次 robocopy 的调用可能看起来如下:
1 | PS C:\> Invoke-Robocopy -Source $env:windir -Destination c:\logs -Filter *.log -Recurse -Open |
以下是封装函数:
1 | #requires -Version 3 |
Cmdlet 内含了纯 .NET 代码,所以感谢 cmdlet,我们通常无需接触 .NET 代码。不过,如果您需要的话仍然可以使用。以下是一系列调用示例,演示了如何调用 .NET 方法:
#requires -Version 2
[System.Convert]::ToString(687687687, 2)
[Math]::Round(4.6)
[Guid]::NewGuid()
[System.IO.Path]::ChangeExtension('c:\test.txt', 'bak')
[System.Net.DNS]::GetHostByName('dell1')
[System.Net.DNS]::GetHostByAddress('192.168.1.124')
[Environment]::SetEnvironmentVariable()
# dangerous, save your work first
[Environment]::FailFast('Oops')
Add-Type -AssemblyName PresentationFramework
$dialog = New-Object Microsoft.Win32.OpenFileDialog
$dialog.ShowDialog()
$dialog.FileName
如果您希望同时执行多个任务,以下有多种方法用 Powershell 实现。一种是使用工作流。它们是 PowerShell 3.0 中引入的:
#requires -Version 3
workflow Test-ParallelForeach
{
param
(
[String[]]
$ComputerName
)
foreach -parallel -throttlelimit 8 ($Machine in $ComputerName)
{
"Begin $Machine"
Start-Sleep -Seconds (Get-Random -min 3 -max 5)
"End $Machine"
}
}
$list = 1..20
Test-ParallelForeach -ComputerName $list | Out-GridView
Test-ParallelForeach
处理一个计算机列表(在这个例子中,是一个数字列表)。它们同时执行。要控制资源的使用,并行循环将节流限制为 8,所以所以在这个例子中的 20 台计算机是 8 个一组处理的。
请注意使用工作流需要更多地了解它们的架构和限制。这个例子关注于工作流提供的并行循环技术。
PowerShell 支持一系列 #requires
语句。技术上它们是注释,但是 PowerShell 会检查这些语句所申明的必要条件,并且如果条件不满足,它将不会执行这个脚本。另外,#requires
语句能快速地告知您运行脚本的前提条件。
#requires -Modules PrintManagement
#requires -Version 3
#Requires -RunAsAdministrator
#requires
语句必须是一个脚本的第一条语句,并且它只对保存的脚本有效。