PowerShell 技能连载 - 查找 Cmdlet

Get-Command 可以用来查找 Cmdlet,但是在 PowerShell 3.0 中,它往往会返回比想象中还要多的 Cmdlet。由于自动加载模块的原因,Get-Command 不仅返回当前已加载 Module 中的 Cmdlet,还会返回所有可用 Module 中的 Cmdlet。

如果您仅希望在当前已加载的 Module 中查找一个 Cmdlet,请使用新的 -ListImported 参数:

PS> Get-Command -Verb Get | Measure-Object
Count    : 422

PS> Get-Command -Verb Get -ListImported | Measure-Object
Count    : 174

查看更多

评论

PowerShell 技能连载 - 从ISE编辑器中粘贴 PowerShell 代码

PowerShell ISE 编辑器的代码复制粘贴功能十分强大,例如将代码复制粘贴到 Microsoft Word 和其它文字处理器。由于 ISE 将剪贴板文字格式化为 RTF 格式,颜色代码将不会丢失。

然而,粘贴的时候字体往往太大或太小。

您可以在 ISE 编辑器中更改它。打开工具 > 选项,然后选择一个不同的字号。您在这儿选择的字号将用于粘贴的代码中。

当您更改完字号并关闭对话框之后,试着用 ISE 编辑器窗口右下角的滑块调整字体显示大小。这里的缩放级别只会影响 ISE 编辑器中的代码,并且不会影响粘贴的代码。

您也可以用鼠标滚轮来调整 ISE 编辑器中的显示字体大小。

查看更多

评论

PowerShell 技能连载 - 创建日历(和日期列表)

以下是一段创建 DateTime 集合的脚本片段。只需要指定年和月,脚本将会针对该月的每一天创建一个 DateTime 对象:

$month = 8
$year = 2013

1..[DateTime]::DaysInMonth($year,$month) |
  ForEach-Object { Get-Date -Day $_ -Month $month -Year $year }

这段代码十分有用:只要加一个日期过滤器,您就可以过滤出工作日来。它将列出指定月份的所有周一至周五(因为它排除了 weekday 0(星期日)和 weekday 6(星期六)):

$month = 8
$year = 2013

1..[DateTime]::DaysInMonth($year,$month) |
  ForEach-Object { Get-Date -Day $_ -Month $month -Year $year } |
  Where-Object { 0,6 -notcontains $_.DayOfWeek }

类似地,以下代码将统计指定月份所有星期三和星期五的天数:

$month = 8
$year = 2013

$days = 1..[DateTime]::DaysInMonth($year,$month) |
  ForEach-Object { Get-Date -Day $_ -Month $month -Year $year } |
  Where-Object { 3,5 -contains $_.DayOfWeek }

$days
"There are {0} Wednesdays and Fridays" -f $days.Count

查看更多

评论

PowerShell 技能连载 - 发生了什么?

经常地,您需要用 PowerShell 来获取数据,并且您需要提取信息的一部分并且把它们用于报表。类似如下:

$serial = Get-WmiObject -Class Win32_OperatingSystem | 
  Select-Object -Property SerialNumber

"Serial Number is $serial" 

但是上述代码产生的结果如下:

Serial Number is @{SerialNumber=00261-30000-00000-AA825}

当您查看 $serial 的值,它看起来似乎很正常:

PS> $serial

SerialNumber
------------
00261-30000-00000-AA825

但问题出在列头(译者注:我们只需要 SerialNumber 的值,而不是需要一个包含 SerialNumber 属性的临时对象)。您可以用 Select-Object 只选出一列,用 -ExpandProperty 而不是 -Property 就可以消除列头:

$serial = Get-WmiObject -Class Win32_OperatingSystem | 
  Select-Object -ExpandProperty SerialNumber

"Serial Number is $serial" 

现在,一切正常了:

Serial Number is 00261-30000-00000-AA825

查看更多

评论

快速替换文本文件中的字符串

不用开什么vim、emac、UltraEdit、Eclipse之类的编辑器了,PowerShell可以帮助手无寸铁的您快速地替换文本文件中的字符串:

dir *.txt -Recurse | % {
    (gc $_ -Raw) | % { $_ `
        -creplace '111', 'AAA' `
        -creplace '222', 'BBB' `
        -creplace '333', 'CCC'
    } | sc $_
}

注意 -creplace 区分大小写,-replace 不区分大小写。并且它们支持正则表达式!

评论

PowerShell 技能连载 - 密码混淆器脚本

曾经需要将密码保存在脚本中?曾经需要自动弹出一个身份验证对话框?对于前者,将密码和其它身份信息存储在脚本中是很糟糕的;对于后者,如果您这么做了的话,至少能使黑客更难于窃取信息。

以下是一个脚本生成器。运行它,并且输入一个域/用户名和密码,脚本生成器会为您生成一段新脚本。

$pwd = Read-Host 'Enter Password' 
$user = Read-Host 'Enter Username'
$key = 1..32 | 
  ForEach-Object { Get-Random -Maximum 256 }

$pwdencrypted = $pwd | 
  ConvertTo-SecureString -AsPlainText -Force | 
  ConvertFrom-SecureString -Key $key

$text = @()
$text += '$password = "{0}"' -f ($pwdencrypted -join ' ') 
$text += '$key = "{0}"' -f ($key -join ' ')
$text += '$passwordSecure = ConvertTo-SecureString -String $password -Key ([Byte[]]$key.Split(" "))' 
$text += '$cred = New-Object system.Management.Automation.PSCredential("{0}", $passwordSecure)' -f $user
$text += '$cred'

$newFile = $psise.CurrentPowerShellTab.Files.Add()
$newFile.Editor.Text = $text | Out-String

这段脚本包含混淆过的密码脚本,看起来大概类似这样:

$password = "76492d1116743f0423413b16050a5345MgB8AFcAMABGAEIANAB1AGEAdQA3ADUASABhAE0AMgBNADUAUwBnAFYAYQA1AEEAPQA9AHwAMgAyAGIAZgA1ADUAZgA0ADIANAA0ADUANwA2ADAAMgA5ADkAZAAxAGUANwA4ADUAZQA4ADkAZAA1AGMAMAA2AA=="
$key = "246 185 95 207 87 105 146 74 99 163 58 194 93 229 80 241 160 35 68 220 130 193 84 113 122 155 208 49 152 86 85 178"
$passwordSecure = ConvertTo-SecureString -String $password -Key ([Byte[]]$key.Split(" "))
$cred = New-Object system.Management.Automation.PSCredential("test\tobias", $passwordSecure)
$cred 

当您运行它,它将生成一个 Credential 对象,您可以立即将它用于身份验证。只要将它传给一个需要 Credential 对象的形参即可。

再强调一下,这并不是安全的。但是要想获取密码的明文还需要更多点知识才行。

查看更多

评论

在PowerShell中以管理员身份运行程序

对于已知的需要以管理员身份运行的命令,我们可以通过这个 Invoke-Admin 函数运行。这个函数确保以管理员身份运行一个程序。如果不是以管理员身份运行,则将弹出 UAC 对话框。

function Invoke-Admin() {
    param ( [string]$program = $(throw "Please specify a program" ),
            [string]$argumentString = "",
            [switch]$waitForExit )

    $psi = new-object "Diagnostics.ProcessStartInfo"
    $psi.FileName = $program 
    $psi.Arguments = $argumentString
    $psi.Verb = "runas"
    $proc = [Diagnostics.Process]::Start($psi)
    if ( $waitForExit ) {
        $proc.WaitForExit();
    }
}

来源:Showing the UAC prompt in PowerShell if the action requires elevation

评论

PowerShell 技能连载 - 检查磁盘分区和数据块大小

WMI 是一个装满信息的宝库。以下这行代码将读取本地分区以及它们的数据块大小信息:

Get-WmiObject -Class Win32_Diskpartition  | 
  Select-Object -Property __Server, Caption, BlockSize 

使用 Get-WmiObject-ComputerName 参数可以对一台或多台机器远程执行同样的操作。

要查看其它所有的 WMI 类,您可以替换掉 Win32_DiskPartition,试试以下的代码:

Get-WmiObject -Class Win32_* -List |
  Where-Object { ($_.Qualifiers | Select-Object -ExpandProperty Name) -notcontains 'Association' } |
  Where-Object { $_.Name -notlike '*_Perf*' }

查看更多

评论

PowerShell 技能连载 - 将Excel导出的CSV转换为UTF-8编码

当您导出 Microsoft Excel 数据表到 CSV 文件时,Excel缺省将保存为 ANSI 编码的 CSV 文件。这是很糟糕的,因为当您用 Import-Csv 导入数据到 PowerShell 中时,特殊字符将会截断(译者注:例如中文出现乱码)。

要确保特殊字符不会丢失,您必须确保导入数据之前 CSV 文件采用的是 UTF-8 编码:

$Path = 'c:\temp\somedata.csv'
(Get-Content -Path $Path) | Set-Content -Path $Path -Encoding UTF8 

查看更多

评论

PowerShell 技能连载 - 查找所有用户脚本

有些时候我们会疑惑当 PowerShell 启动的时候,将执行哪些启动脚本。它们数量很多,而且各不相同,要看您运行的是 PowerShell 控制台,ISE,还是其他宿主。

然而,了解您的用户脚本是十分重要的。它们决定了应用到 PowerShell 环境的配置。

这个 Get-PSProfileStatus 函数列出了所有宿主(PowerShell 环境)可能用到的的启动脚本。它也显示了哪些脚本是物理存在的。

function Get-PSProfileStatus
{
    $profile | 
      Get-Member -MemberType NoteProperty |
      Select-Object -ExpandProperty Name | 
      ForEach-Object {
        $_, (Split-Path $profile.$_ -Leaf), (Split-Path $profile.$_), 
                              (Test-Path -Path $profile.$_) -join ',' |
          ConvertFrom-Csv -Header Profile, FileName, FolderName, Present
        }
}

Get-PSProfileStatus

结果看起来类似这样:

将结果用管道输出到 Out-GridView 来查看,避免截断字符被截断:

Get-PSProfileStatus | Out-GridView

查看更多

评论