PowerShell 技能连载 - 远程更新组策略
适用于 Windows 8.1 或 Server 2012 R2
要更新远程计算机上的组策略设置,请使用 Invoke-GPUpdate
,并且传入希望更新设置的计算机名。
Invoke-GPUpdate
在远程计算机上创建“gpupdate
”计划任务。您可以使用 –RandomDelayInMinutes
指定一个 0 至 44640 分钟(31 天)之间的值。该 cmdlet 将使用一个随机的时间因子来避免网络阻塞。
适用于 Windows 8.1 或 Server 2012 R2
要更新远程计算机上的组策略设置,请使用 Invoke-GPUpdate
,并且传入希望更新设置的计算机名。
Invoke-GPUpdate
在远程计算机上创建“gpupdate
”计划任务。您可以使用 –RandomDelayInMinutes
指定一个 0 至 44640 分钟(31 天)之间的值。该 cmdlet 将使用一个随机的时间因子来避免网络阻塞。
适用于 Windows 8.1 和 Server 2012 R2
Windows 8.1 和 Server 2012 R2 带来了一个叫做“PrintManagement”的模块。它包含了管理本地和远程打印机所需的所有 Cmdlet。
以下是一个示例脚本,演示了安装打印机驱动、设置打印机端口、安装打印机、共享该打印机,以及设置某些打印机属性的过程。
$ComputerName = $env:COMPUTERNAME
$DriverName = 'Samsung SCX-483x 5x3x Series XPS'
$IPAddress = '192.168.2.107'
$PortName = 'NetworkPrint_192.168.2.107'
$PrinterName = 'BWPrint'
$ShareName = 'Office 12'
Add-PrinterDriver -ComputerName $ComputerName -Name $DriverName
Add-PrinterPort -Name $PortName -ComputerName $ComputerName
Add-Printer -ComputerName $ComputerName -Name $PrinterName -DriverName $DriverName -Shared -ShareName $ShareName -PortName $PortName
Set-PrintConfiguration -ComputerName $ComputerName -PrinterName $PrinterName -PaperSize A4
要使用它,请确保您修改了 $IPAddress
并指向一个存在的打印机。请将 $ComputerName
修改指向一个远程计算机而不是您的本地计算机。
要列出 PrintManagement
模块所带的所有 Cmdlet,请试试以下代码:
PS> Get-Command -Module PrintManagement
CommandType Name ModuleName
----------- ---- ----------
Function Add-Printer PrintManagement
Function Add-PrinterDriver PrintManagement
Function Add-PrinterPort PrintManagement
Function Get-PrintConfiguration PrintManagement
Function Get-Printer PrintManagement
Function Get-PrinterDriver PrintManagement
Function Get-PrinterPort PrintManagement
Function Get-PrinterProperty PrintManagement
Function Get-PrintJob PrintManagement
Function Read-PrinterNfcTag PrintManagement
Function Remove-Printer PrintManagement
Function Remove-PrinterDriver PrintManagement
Function Remove-PrinterPort PrintManagement
Function Remove-PrintJob PrintManagement
Function Rename-Printer PrintManagement
Function Restart-PrintJob PrintManagement
Function Resume-PrintJob PrintManagement
Function Set-PrintConfiguration PrintManagement
Function Set-Printer PrintManagement
Function Set-PrinterProperty PrintManagement
Function Suspend-PrintJob PrintManagement
Function Write-PrinterNfcTag PrintManagement
如您所见,它们实际上是 PowerShell 函数而不是二进制 Cmdlet。
请在 PowerShell 控制台中执行本脚本
今天在群里看到一个数码雨的课题,试着实现了一下:
【话痨】powershell传教士(1328486072) 12:58:11
话说有人用bat写出了数码雨,谁也用powershell写一个,我用powershell写了几个,总感觉不对。
【话痨】powershell传教士(1328486072) 12:58:52
有人对命令行数码雨,感兴趣么?
根据传教士的提示,改了一下,避免了闪烁。
1 | ## Prepare the screen |
您也可以在这里下载 Matrix.ps1
适用于 PowerShell 所有版本
PowerShell 为多数常见的 .NET 类型定义了一个短名字。要查看已有多少个 .NET 类型定义了短名称,请使用以下代码:
PS> [System.Management.Automation.LanguagePrimitives]::ConvertTypeNameToPSTypeName("System.String")
[string]
PS> [System.Management.Automation.LanguagePrimitives]::ConvertTypeNameToPSTypeName("System.Int32")
[int]
PS> [System.Management.Automation.LanguagePrimitives]::ConvertTypeNameToPSTypeName("System.Management.ManagementObject")
[wmi]
PS> [System.Management.Automation.LanguagePrimitives]::ConvertTypeNameToPSTypeName("System.DirectoryServices.DirectoryEntry")
[adsi]
PS>
要查用另一种方法看真实的 .NET 名称,请使用以下方法:
PS> [string].FullName
System.String
PS> [int].FullName
System.Int32
PS> [wmi].FullName
System.Management.ManagementObject
PS> [adsi].FullName
System.DirectoryServices.DirectoryEntry
PS>
通过这个技巧,您还可以更好地理解 PowerShell 转换数据类型的机制:
PS> [System.Management.Automation.LanguagePrimitives]::ConvertTypeNameToPSTypeName("UInt8")
[Byte]
PS>
这表明了,当 PowerShell 遇到一个无符号 8 位整型数值,将自动把它转换为一个 Byte 数据。整个魔法是由 ConvertTypeNameToPSTypeName()
完成的。在内部,PowerShell 使用一个检索表来转换特定的数据类型:
$field = [System.Management.Automation.LanguagePrimitives].GetField('nameMap', 'NonPublic,Static')
$field.GetValue([System.Management.Automation.LanguagePrimitives])
该检索表看起来类似这样:
Key Value
--- -----
SInt8 SByte
UInt8 Byte
SInt16 Int16
UInt16 UInt16
SInt32 Int32
UInt32 UInt32
SInt64 Int64
UInt64 UInt64
Real32 Single
Real64 double
Boolean bool
String string
DateTime DateTime
Reference CimInstance
Char16 char
Instance CimInstance
BooleanArray bool[]
UInt8Array byte[]
SInt8Array Sbyte[]
UInt16Array uint16[]
SInt16Array int64[]
UInt32Array UInt32[]
SInt32Array Int32[]
UInt64Array UInt64[]
SInt64Array Int64[]
Real32Array Single[]
Real64Array double[]
Char16Array char[]
DateTimeArray DateTime[]
StringArray string[]
ReferenceArray CimInstance[]
InstanceArray CimInstance[]
Unknown UnknownType
适用于 PowerShell 3.0 及以上版本
在 PowerShell ISE 中要将 PowerShell 的代码转为全大写,请选中文本,并按下 CTRL + SHIFT + U
。
To turn text to all lowercase letters, press CTRL+U.
要将文本转为全小写,请按 CTRL+U
。
适用于 PowerShell 3.0 及以上版本
要永久地映射一个网络驱动器,请使用 New-PSDrive
加上 -Persist
参数。这个参数使得驱动器在 PowerShell 之外可见。
要真正地创建一个永久的网络驱动器,请确保加上 -Scope Global
。如果 New-PSDrive
在全局作用域范围之外运行(例如,在一个脚本中运行),该驱动器只会在脚本运行时出现在文件管理器中。
这个实例代码演示了如何映射一个网络驱动器:
New-PSDrive -Name k -PSProvider FileSystem -Root \\storage2\vid -Persist -Scope Global
适用于 PowerShell 所有版本
如果您的脚本希望输出警告或错误信息,您可以使用 Write-Warning
或 Write-Error
指令。两个 cmdlet 都会使用缺省的 PowerShell 颜色来显示警告和错误。然而,这两个 cmdlet 也会为您的输出结果套用一个文字模板:
PS> Write-Warning -Message 'This is a warning'
WARNING: This is a warning
PS> Write-Error -Message 'Something went wrong'
Write-Error -Message 'Something went wrong' : Something went wrong
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
Write-Error
添加了一堆无意义的异常详细信息,而您所需要的只是错误文本。一个更好的方式是:
PS> $host.UI.WriteErrorLine('Something went wrong...')
Something went wrong...
警告和错误的颜色可以通过这种方式配置:
PS> $host.UI.WriteErrorLine('Something went wrong...')
Something went wrong...
PS> $host.PrivateData.ErrorBackgroundColor = 'White'
PS> $host.UI.WriteErrorLine('Something went wrong...')
Something went wrong...
PS> $host.PrivateData
(...)
ErrorForegroundColor : #FFFF0000
ErrorBackgroundColor : #FFFFFFFF
WarningForegroundColor : #FFFF8C00
WarningBackgroundColor : #00FFFFFF
VerboseForegroundColor : #FF00FFFF
VerboseBackgroundColor : #00FFFFFF
DebugForegroundColor : #FF00FFFF
DebugBackgroundColor : #00FFFFFF
(...)
适用于 PowerShell 2.0 及以上版本
这个例子演示了两件事情:如何限制一个参数为指定的数据类型、如何使用 .NET 方法来将 IP 地址转化为机器名:
function Resolve-IPAddress
{
param (
[IPAddress]
$IPAddress
)
[Net.DNS]::GetHostByAddress($IPAddress)
}
通过为 $IPAddress
参数前附加一个类型(例如“IPAddress
”),您可以让 PowerShell 来校验输入数据的合法性。
“System.Net.DNS
” .NET 类型提供了许多有用的静态方法供您解析 IP 地址。请注意在 PowerShell 中您不需要为 .NET 类型指定“System”命名空间。如果您愿意,您也可以使用完整的“`System.Net.DNS”全名。
这是您使用了新的 Resolve-IPAddress
函数的效果:
PS> Resolve-IPAddress -IPAddress 127.0.0.1
HostName Aliases AddressList
-------- ------- -----------
TobiasAir1 {} {127.0.0.1}
PS> Resolve-IPAddress -IPAddress 300.200.100.1
Resolve-IPAddress : Cannot process argument transformation on parameter
'IPAddress'. Cannot convert value "300.200.100.1" to type "System.Net.IPAddress".
Error: "An invalid IP address was specified."
At line:1 char:30
+ Resolve-IPAddress -IPAddress 300.200.100.1
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Resolve-IPAddress], ParameterBindin
gArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Resolve-IPAddres
s
适用于 PowerShell 3.0 及以上版本
PowerShell ISE 只支持行断点:它们的作用是当调试器命中指定的行时,使代码暂停执行。您可以在 PowerShell ISE 中按 F9
来切换行断点。只需要保证脚本已经保存。未保存的脚本(“无标题”)中的断点是无效的。
一个更复杂的做法是使用动态(或称为“条件”)断点。它们并不是关联于某一行上而是和某一种情况有关联。
要在某个变量被赋予一个新值的时候使脚本停下来,请使用这段示例代码(请先保存后执行):
$bp = Set-PSBreakpoint -Variable a -Mode Write -Script $psise.CurrentFile.FullPath
$a = 1
$a
$a
$a = 200
$a
Remove-PSBreakpoint -Breakpoint $bp
当您运行它时,PowerShell 调试器将会在 $a
被赋予一个新值的时候暂停脚本执行。
您甚至可以为它绑定一个更复杂的条件。这个例子将只会在对 $a
赋予一个大于 100 的整数值时才使脚本暂停。
$Condition = { if ($a -is [Int] -and $a -gt 100) { break } }
$bp = Set-PSBreakpoint -Variable a -Mode Write -Script $psise.CurrentFile.FullPath -Action $Condition
$a = 1
$a
$a
$a = 200
$a
Remove-PSBreakpoint -Breakpoint $bp
适用于 Windows 7/Server 2008 R2
要检测一个脚本是运行在 32 位环境还是 64 位环境是十分简单的:只需要检查指针的大小,看是等于 4 字节还是 8 字节:
if ([IntPtr]::Size -eq 8)
{
'64-bit'
}
else
{
'32-bit'
}
不过这并不会告诉您操作系统的类型。这是由于 PowerShell 脚本可以在 64 位机器中运行在 32 位进程里。
要检测 OS 类型,请试试这段代码:
if ([Environment]::Is64BitOperatingSystem)
{
'64-bit'
}
else
{
'32-bit'
}
而且,Environment
类也可以检查您的进程类型:
if ([Environment]::Is64BitProcess)
{
'64-bit'
}
else
{
'32-bit'
}