PowerShell 技能连载 - 键盘技巧
在 PowerShell ISE 4.0 控制台窗格中,按住 CTRL
键,然后按 向上
键,可以将光标从命令行中移到结果区域中。
在 PowerShell ISE 4.0 控制台窗格中,按住 CTRL
键,然后按 向上
键,可以将光标从命令行中移到结果区域中。
LDAP 查询的功能非常强大,可以帮助查找缺少信息的账户。
这段代码将返回所有带邮箱地址的 Active Directory 用户:
$searcher = [ADSISearcher]"(&(sAMAccountType=$(0x30000000))(mail=*))"
$searcher.FindAll() |
ForEach-Object { $_.GetDirectoryEntry() } |
Select-Object -Property sAMAccountName, name, mail
如果您想查询相反的内容,请通过“!
”号进行相反的查询。以下代码可以返回所有缺少邮箱地址的 Active Directory 用户:
$searcher = [ADSISearcher]"(&(sAMAccountType=$(0x30000000))(!(mail=*)))"
$searcher.FindAll() |
ForEach-Object { $_.GetDirectoryEntry() } |
Select-Object -Property sAMAccountName, name, mail
编号 | 发布时间 | 标题 | |
---|---|---|---|
Vol.01 | 2013年06月 | 文件系统任务 | 下载 |
Vol.02 | 2013年07月 | 数组和哈希表 | 下载 |
Vol.03 | 2013年08月 | 日期、时间和文化 | 下载 |
Vol.04 | 2013年09月 | 对象和类型 | 下载 |
Vol.05 | 2013年10月 | WMI | 下载 |
Vol.06 | 2013年11月 | 正则表达式 | 下载 |
Vol.07 | 2013年12月 | 函数 | 下载 |
Vol.08 | 2013年12月 | 静态 .NET 方法 | 下载 |
Vol.09 | 2014年01月 | 注册表 | 下载 |
Vol.10 | 2014年02月 | Internet 相关任务 | 下载 |
Vol.11 | 2014年03月 | XML 相关任务 | 下载 |
Vol.12 | 2014年08月 | 安全相关任务 | 下载 |
如果您(和我一样)足够懒,也可以用这样一行 PowerShell 代码来下载:
1..12 | ForEach-Object { Invoke-WebRequest "http://powershell.com/cs/PowerTips_Monthly_Volume_$_.pdf" -OutFile "PowerTips_Monthly_Volume_$_.pdf" }
译者注:您没有看错!这是近期最邪恶的一个技巧,文末有译者机器上的实验效果。
厌倦了每次自己想蹩脚的借口?以下脚本能让您每调用一次 Get-Excuse
就得到一个新的接口!您所需的一切只是 Internet 连接:
function Get-Excuse
{
$url = 'http://pages.cs.wisc.edu/~ballard/bofh/bofhserver.pl'
$ProgressPreference = 'SilentlyContinue'
$page = Invoke-WebRequest -Uri $url -UseBasicParsing
$pattern = '<br><font size = "\+2">(.+)'
if ($page.Content -match $pattern)
{
$matches[1]
}
}
如果您需要通过代理服务器或者身份认证来访问 Internet,那么请查看函数中 Invoke-WebRequest
的参数。您可以通过它提交代理服务器信息,例如身份验证信息。
译者注:以下是
Get-Excuse
为笔者找的“借口”,很有创意吧 ;-)
PS >Get-Excuse
your process is not ISO 9000 compliant
PS >Get-Excuse
evil hackers from Serbia.
PS >Get-Excuse
piezo-electric interference
PS >Get-Excuse
Bogon emissions
PS >Get-Excuse
because Bill Gates is a Jehovah's witness and so nothing can work on St. Swithin's day.
PS >Get-Excuse
Your cat tried to eat the mouse.
PS >Get-Excuse
It works the way the Wang did, what's the problem
PS >Get-Excuse
Telecommunications is upgrading.
PS >Get-Excuse
Your computer's union contract is set to expire at midnight.
PS >Get-Excuse
Daemon escaped from pentagram
PS >Get-Excuse
nesting roaches shorted out the ether cable
PS >Get-Excuse
We ran out of dial tone and we're and waiting for the phone company to deliver another bottle.
PS >Get-Excuse
Root nameservers are out of sync
PowerShell 保存了您键入的所有命令列表,但是当您关闭 PowerShell 时,这个列表就丢失了。
以下是一个保存当前命令历史到文件的单行代码:
Get-History | Export-Clixml $env:temp\myHistory.xml
当您启动一个新的 PowerShell 控制台或 ISE 编辑器实例时,您可以将保存的历史读入 PowerShell:
Import-Clixml $env:\temp\myHistory.xml | Add-History
不过,加载历史并不会影响键盘缓冲区,所以按下上下键并不会显示新导入的历史条目。然而,您可以用 TAB 自动完成功能来查找您之前输入的命令:
#(KEYWORD) <-现在按下(TAB)键!
要正确地将单词首字母转换为大写,您可以用正则表达式或者一点系统函数:
用正则表达式的话,您可以这样做:
$sentence = 'here is some text where i would like the first letter to be capitalized.'
$pattern = '\b(\w)'
[RegEx]::Replace($sentence, $pattern, { param($x) $x.Value.ToUpper() })
用系统函数的话,这样做可以达到相同的效果:
$sentence = 'here is some text where i would like the first letter to be capitalized.'
(Get-Culture).TextInfo.ToTitleCase($sentence)
正则表达式稍微复杂一点,但是功能更多。例如如果出于某种古怪的原因,您需要将每个单词的首字母替换为它的 ASCII 码,那么正则表达式可以轻松地实现:
$sentence = 'here is some text where i would like the first letter to be capitalized.'
$pattern = '\b(\w)'
[RegEx]::Replace($sentence, $pattern, { param($x) [Byte][Char]$x.Value })
PowerShell 可以操作 COM 对象,例如 Outlook 应用程序。以下简单的两行代码能返回当前的 Outlook 配置文件名:
$outlookApplication = New-Object -ComObject Outlook.Application
$outlookApplication.Application.DefaultProfileName
从 PowerShell 4.0 开始,方法名可以是一个变量。以下是一个简单的例子:
$method = 'ToUpper'
'Hello'.$method()
当您需要调用的方法须通过一段脚本计算得到的时候,这个特性十分有用。
function Convert-Text
{
param
(
[Parameter(Mandatory)]
$Text,
[Switch]$ToUpper
)
if ($ToUpper)
{
$method = 'ToUpper'
}
else
{
$method = 'ToLower'
}
$text.$method()
}
以下是用户调用该函数的方法:
PS> Convert-Text 'Hello'
hello
PS> Convert-Text 'Hello' -ToUpper
HELLO
缺省情况下,该函数将文本转换为小写。当指定了开关参数 -ToUpper
时,函数将文本转换为大写。由于动态方法特性的支持,该函数不需要为此写两遍代码。
译者注:在旧版本的 PowerShell 中,您可以通过 .NET 方法(而不是脚本方法)中的反射来实现相同的目的。虽然它不那么整洁,但它能运行在 PowerShell 4.0 以下的环境:
function Convert-Text
{
param
(
[Parameter(Mandatory)]
$Text,
[Switch]$ToUpper
)
if ($ToUpper)
{
$method = 'ToUpper'
}
else
{
$method = 'ToLower'
}
$methodInfo = $Text.GetType().GetMethod($method, [type[]]@())
$methodInfo.Invoke($Text, $null)
}
在 PowerShell 中,您可以使用变量来指代属性名。这段示例脚本定义了四个 profile 的属性名,然后在一个循环中分别查询这些属性值:
$list = 'AllUsersAllHosts','AllUsersCurrentHost','CurrentUserAllHosts','CurrentUserCurrentHost'
foreach ($property in $list)
{
$profile.$property
}
您也可以在一个管道中使用它:
'AllUsersAllHosts','AllUsersCurrentHost','CurrentUserAllHosts','CurrentUserCurrentHost' |
ForEach-Object { $profile.$_ }
通过这种方式,您可以检查和返回 PowerShell 当前使用的所有 profile:
'AllUsersAllHosts','AllUsersCurrentHost','CurrentUserAllHosts','CurrentUserCurrentHost' |
ForEach-Object { $profile.$_ } |
Where-Object { Test-Path $_ }
类似地,您可以首先使用 Get-Member
来获取一个指定对象包含的所有属性。以下代码可以返回 PowerShell 的“PrivateData”对象中所有名字包含“color”的属性:
$host.PrivateData | Get-Member -Name *color* | Select-Object -ExpandProperty Name
接下来,您可以用一行代码获取所有的颜色设置:
$object = $host.PrivateData
$object | Get-Member -Name *color* -MemberType *property | ForEach-Object {
$PropertyName = $_.Name
$PropertyValue = $object.$PropertyName
"$PropertyName = $PropertyValue"
} |
Out-GridView
如果您只是需要替换文本中字符出现的所有位置,这是很简单的。以下可以将文本中所有的“l”变为大写:
"Hello World".Replace('l', 'L')
然而有些时候,您需要替换特定位置的某几个字符。我们假设您的文本是一个比特掩码,并且您需要对某些比特置位或清除。以上代码是不能用的,因为它一口气改变了所有的位:
PS> "110100011110110".Replace('1', '0')
000000000000000
而且您也不能通过索引来改变字符。您可以读取一个字符(例如检查某一个位是否为“1”),但您无法改变它的值:
PS> "110100011110110"[-1] -eq '1'
False
PS> "110100011110110"[-2] -eq '1'
True
PS> "110100011110110"[-2] = '0'
无法对 System.String 类型的对象进行索引。
要改变一个字符串中的某些字符,请将它转换为一个 StringBuilder
:
PS> $sb = New-Object System.Text.StringBuilder("1101100011110110")
PS> $sb[-1]
0
PS> $sb[-1] -eq '1'
False
PS> $sb[-2] -eq '1'
True
PS> $sb[-2] = '0'
PS> $sb[-2] -eq '1'
False
PS> $sb.ToString()
110100011110100
以下是将二进制转换为十进制格式的方法:
PS> $sb.ToString()
110100011110100
PS> [System.Convert]::ToInt64($sb.ToString(), 2)
26868