PowerShell 技能连载 - PowerShell 技能连载 - 配置 PowerShell 的步骤(第 3 部分)

适用于 PowerShell 所有版本

如果您在家中或其它不重要的场合使用 PowerShell,那么可以通过以下步骤使 PowerShell 发挥最大功能。

要在您自己的的机器上启用 PowerShell 远程操作,您需要在您的机器上启用 PowerShell 远程操作功能。实现的方式是用管理员权限启动 PowerShell,然后运行该命令:

1
PS> Enable-PSRemoting -SkipNetworkProfileCheck -Force

请注意 -SkipNetworkProfileCheck 是 PowerShell 3.0 引入的概念。如果您仍在 使用 PowerShell 2.0,请忽略这个参数。如果 PowerShell 提示公用网络连接可用,您需要手动临时禁用公用网络连接。

该命令在您的机器上启用 PowerShell 远程操作。其他人现在可以连接到您的计算机,如果他是您计算机上的 Administrators 组成员。

然而,您只能用 Kerberos 身份验证方式来连接到别的计算机。所以此时,远程操作只适用于域环境。如果您在一个简单的点对点网络环境中或是想跨域使用远程操作功能,那么需要启用 NTLM 验证。请注意:只需要在客户端设置。不是在您想连接的目标机器上设,而是在您发起远程操作的机器上设:

1
PS> Set-Item -Path WSMan:\localhost\Client\TrustedHosts -Value * -Force

使用“*”允许您通过 NTLM 验证方式连接到任何目标机器。由于 NTLM 是一种非双向认证方式,所以当您使用该方式连接到一台不受信任或可能已被入侵的机器时,会增加安全风险。所以最好不要用“*”,而是指定 IP 地址或 IP 地址段,例如“10.10.*”。

当设置好 PowerShell 远程操作之后,您可以开始使用。

这行代码将会在 ABC 机器上运行任意的 PowerShell 代码(需要您事先在 ABC 机器上启用远程操作功能,并且拥有 ABC 机器上的管理员权限):

1
PS> Invoke-Command -ScriptBlock { "Hello" > c:\IwasHERE.txt } -ComputerName ABC

这段代码将实现同样的效果,但这里您需要显式地制定凭据。当您指定了一个账户,请确定指定了域名和用户名。如果它不是一个域账户,请指定机器名和用户名:

1
Invoke-Command -ScriptBlock { "Hello" > c:\IwasHERE.txt } -ComputerName ABC -Credential ABC\localAdminAccount

请注意:当您想用非 Kerberos 验证的时候,加入域的计算机需要使用 -Credential 参数。

PowerShell 技能连载 - 配置 PowerShell 的步骤(第 2 部分)

适用于 PowerShell 2.0 及以上版本

如果您在家中或其它不重要的场合使用 PowerShell,那么可以通过以下步骤使 PowerShell 发挥最大功能。

要允许系统管理员远程连接到您的机器并运行 Get-ProcessGet-Service 等 cmdlets,您也许需要启用远程管理的防火墙例外规则。请以管理员身份打开 PowerShell 并运行这段代码:

1
2
3
4
5
6
7
8
9
10
PS> netsh firewall set service remoteadmin enable

IMPORTANT: Command executed successfully.
However, "netsh firewall" is deprecated;
use "netsh advfirewall firewall" instead.
For more information on using "netsh advfirewall firewall" commands
instead of "netsh firewall", see KB article 947709
at http://go.microsoft.com/fwlink/?linkid=121488 .

Ok.

该命令返回的信息告诉我们该命令已过时,有一个更新的命令替代了它,但它任然可用并启用了防火墙例外。新的命令更难使用,因为它的参数是本地化的,并且您需要知道防火墙例外的确切名称。

要真正地用上 cmdlet 的远程功能,您还需要启用 RemoteRegistry 服务并将它设为自动启动:

1
2
3
PS> Start-Service RemoteRegistry

PS> Set-Service -Name Remoteregistry -StartupType Automatic

您现在可以使用 Get-ProcessGet-Service 或其它暴露了 -ComputerName 参数的 cmdlet 来远程连接到您的计算机,假设运行这些 cmdlet 的用户拥有您系统上的管理员权限。

在简单的点对点家庭环境中,为每台计算机的 Administrator 账号设置相同的名字就足够了。

PowerShell 技能连载 - 配置 PowerShell 的步骤(第 1 部分)

适用于 PowerShell 2.0 及以上版本

如果您在家中或其它不重要的场合使用 PowerShell,那么可以通过以下步骤使 PowerShell 发挥最大功能。

您可以通过以下代码查看正在使用的 PowerShell 版本:

1
2
3
PS> $PSVersionTable.PSVersion.Major

4

如果版本号小于 4,请审查一下为什么使用过期的版本,是不是可以升级了。

要启用脚本执行功能,请运行以下代码:

1
PS> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force

您现在可以自由地执行任意位置的脚本了。如果您是初学者并且希望得到更多的安全保障,请将“Bypass”改为“RemoteSigned”。这将防止您运行下载自 Internet 或电子邮件附件的脚本。它也将防止您运行您拥有的域之外的脚本。

PowerShell 技能连载 - 数组中的空值

适用于 PowerShell 所有版本

当您将 NULL 值赋给数组元素时,它们会记入数组元素中,但不会输出(毕竟,它们是所谓的空值)。这会导致调试时的困难。所以当数组的大小看起来和内容不一样时,请查查是否有空值:

1
2
3
4
5
6
7
8
9
$a = @()
$a += 1
$a += $null
$a += $null
$a += 2

1
2
Count: 4

PowerShell 技能连载 - 随机排列数字列表

适用于 PowerShell 所有版本

这行代码将输入一个数字列表并对它们随机排序:

1
Get-Random -InputObject 1, 2, 3, 5, 8, 13 -Count ([int]::MaxValue)

也可以用管道,不过速度更慢:

1
1, 2, 3, 5, 8, 13 | Sort-Object -Property { Get-Random }

PowerShell 技能连载 - 读取磁盘和分区信息

适用于 Windows 8.1 / Server 2012 R2

Windows 8.1 和 Server 2012 R2 带来的许多客户端和服务器 cmdlet 可以极大地简化磁盘的管理。

让我们从查看磁盘和分区开始。这将列出所有加载的磁盘:

1
PS> Get-Disk

这将列出分区:

1
PS> Get-Partition

这两个 cmdlet 都位于“Storage”模块中:

1
2
3
4
5
PS> Get-Command -Name Get-Disk | Select-Object -ExpandProperty Module

ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 2.0.0.0 Storage {Add-InitiatorIdToMas...

这将列出该模块中的所有存储管理命令:

1
2
3
4
5
6
7
8
9
10
11
PS> Get-Command -Module storage

CommandType Name ModuleName
----------- ---- ----------
Alias Flush-Volume Storage
Alias Initialize-Volume Storage
Alias Write-FileSystemCache Storage
Function Add-InitiatorIdToMaskingSet Storage
Function Add-PartitionAccessPath Storage
Function Add-PhysicalDisk Storage
(...)

PowerShell 技能连载 - 查看 Windows 版本

适用于 PowerShell 所有版本

您有安装 Windows 8.1 Basic 版、Pro 版,或 Enterprise 版吗?查看 Windows 版本号很容易,但查看具体是哪个子系列则不这么容易。

最好的方法是,获取 SKU 号,它能精确地体现 Windows 的版本类型,但如何将数字转化为一个有意义的名字也不太容易:

1
2
3
PS> Get-WmiObject -Class Win32_OperatingSystem | Select-Object -ExpandProperty OperatingSystemSKU

48

一个稍好的方式是用这段代码返回您当前使用的许可类型的明确的文字描述:

1
2
3
PS> Get-WmiObject SoftwareLicensingProduct -Filter 'Name like "Windows%" and LicenseStatus=1' | Select-Object -ExpandProperty Name

Windows(R), Professional edition

另一种方法也可以返回 Windows 的主要版本信息:

1
2
3
PS> Get-WmiObject -Class Win32_OperatingSystem | Select-Object -ExpandProperty Caption

Microsoft Windows 8.1 Pro

PowerShell 技能连载 - Join-Path 遇上不存在的驱动器会失败

适用于 PowerShell 所有版本

您可能已经使用 Join-Path 通过父文件夹和文件来创建路径名。这个 cmdlet 在合并路径元素的时候能够正确地处理反斜杠的个数:

1
2
3
4
5
$part1 = 'C:\somefolder\'
$part2 = '\myfile.txt'
$result = Join-Path -Path $part1 -ChildPath $part2

$result

然而,如果路径元素存在,Join-Path 将会失败。所以您无法为一个没有加载的驱动器创建路径:

1
2
3
4
5
6
7
$part1 = 'L:\somefolder\'
$part2 = '\myfile.txt'
$result = Join-Path -Path $part1 -ChildPath $part2

$result

Join-Path : Cannot find drive. A drive with the name 'L' does not exist.

其实,Join-Path 所做的事也可以通过手工很好地完成。这段代码将合并两段路径元素并且能处理好反斜杠:

1
2
3
4
5
$part1 = 'L:\somefolder\'
$part2 = '\myfile.txt'
$result = $part1.TrimEnd('\') + '\' + $part2.TrimStart('\')

$result

如果您在 Windows 功能中启用了 Hyper-V 的 PowerShell 模块(如前一个技能中描述的一样的),您现在就可以通过 PowerShell 管理虚拟磁盘。

PowerShell 技能连载 - 用 Cmdlet 管理虚拟硬盘驱动器

适用于 Windows 8.1 Pro/Enterprise 或 Server 2012 R2

Windows 8.1 和 Server 2012 R2 带来一系列额外的 cmdlet 命令,有一部分用于管理虚拟磁盘。不过,在使用这些 cmdlet 之前,您需要先启用“Hyper-V 角色”(请注意需要 Windows 8.1 Pro 或 Enterprise 版才支持客户端的 Hyper-V。“Home”版则不支持该功能)。

在 Windows 8.1 中,您需要手动做以下操作:打开控制面板,进入程序/程序和功能。您也可以在 PowerShell 中键入“appwiz.cpl”打开该功能。

下一步,点击“启用或关闭 Windows 功能”。这将打开一个列出所有功能的对话框。请定位到“Hyper-V”节点并启用它。然后点击 OK。如果找不到“Hyper-V”节点,那么您的 Windows 版本不支持客户端的 Hyper-V。如果“Hyper-V 平台”选项呈灰色,那么您需要在计算机的 BIOS 设置中启用虚拟化支持。

安装该功能需要几秒钟。当安装完成以后,您就可以使用一系列新的 cmdlet:

1
2
3
4
5
6
7
8
9
10
PS> Get-Command -Module Hyper-V

CommandType Name ModuleName
----------- ---- ----------
Cmdlet Add-VMDvdDrive Hyper-V
Cmdlet Add-VMFibreChannelHba Hyper-V
Cmdlet Add-VMHardDiskDrive Hyper-V
Cmdlet Add-VMMigrationNetwork Hyper-V
Cmdlet Add-VMNetworkAdapter Hyper-V
(...)

PowerShell 技能连载 - 使用 IPv4 来 Ping

适用于 PowerShell 所有版本

您可以像其它命令一样在 PowerShell 脚本中使用 ping.exe。向 ping 命令加入“-4”参数之后,您可以强制 ping 命令使用 IPv4 协议(也可以用“-6”参数强制使用 IPv6)。

PS> ping localhost -4