PowerShell 技能连载 - 多个返回值

一个PowerShell函数可以有多个返回值。要接收这些返回值,只需要将返回值赋给多个变量:

function Get-DateTimeInfo
{
    # Value 1
    Get-Date -Format 'dddd'

    # Value 2
    Get-Date -Format 'MMMM'

    # Value 3
    Get-Date -Format 'HH:mm:ss'
}

$day, $month, $time = Get-DateTimeInfo

"Today is $day, the month is $month, and it is $time"

PowerShell 技能连载 - 汇总索引

2013 年

2013 年 09 月

2013 年 10 月

2013 年 11 月

2013 年 12 月

2014 年

2014 年 01 月

2014 年 02 月

2014 年 03 月

2014 年 04 月

2014 年 05 月

2014 年 06 月

2014 年 07 月

2014 年 08 月

2014 年 09 月

2014 年 10 月

2014 年 11 月

2014 年 12 月

2015 年

2015 年 01 月

2015 年 02 月

2015 年 03 月

2015 年 04 月

2015 年 05 月

2015 年 06 月

2015 年 07 月

2015 年 08 月

2015 年 09 月

2015 年 10 月

2015 年 11 月

2015 年 12 月

2016 年

2016 年 01 月

2016 年 02 月

2016 年 08 月

2016 年 09 月

2016 年 10 月

2016 年 11 月

2016 年 12 月

2017 年

2017 年 01 月

2017 年 02 月

2017 年 03 月

2017 年 04 月

2017 年 05 月

2017 年 06 月

2017 年 07 月

2017 年 08 月

2017 年 09 月

2017 年 10 月

2017 年 11 月

2017 年 12 月

2018 年

2018 年 01 月

2018 年 02 月

2018 年 03 月

2018 年 04 月

2018 年 05 月

2018 年 06 月

2018 年 07 月

2018 年 08 月

2018 年 09 月

2018 年 10 月

2018 年 11 月

2018 年 12 月

2019 年

2019 年 01 月

2019 年 02 月

2019 年 03 月

2019 年 04 月

2019 年 05 月

2019 年 06 月

2019 年 07 月

2019 年 08 月

2019 年 09 月

2019 年 10 月

2019 年 11 月

2019 年 12 月

2020 年

2020 年 01 月

2020 年 02 月

2020 年 03 月

2020 年 04 月

2020 年 05 月

2020 年 06 月

2020 年 07 月

2020 年 08 月

2020 年 09 月

2020 年 10 月

2020 年 11 月

2020 年 12 月

2021 年

2021 年 01 月

2021 年 02 月

2021 年 03 月

2021 年 04 月

2021 年 05 月

2021 年 06 月

2021 年 07 月

2021 年 08 月

2021 年 09 月

2021 年 10 月

2021 年 11 月

2021 年 12 月

2022 年

2022 年 01 月

2022 年 02 月

2022 年 03 月

2022 年 04 月

2022 年 05 月

2022 年 06 月

2022 年 07 月

2022 年 08 月

2022 年 09 月

2022 年 10 月

2022 年 11 月

2023 年

2023 年 01 月

2023 年 02 月

2023 年 03 月

2023 年 04 月

2023 年 05 月

2023 年 06 月

2023 年 07 月

2023 年 08 月

2023 年 09 月

2023 年 10 月

2023 年 11 月

2024 年

2024 年 01 月

2024 年 02 月

2024 年 03 月

2024 年 08 月

PowerShell 技能连载 - 处理文件系统路径(第3部分)

在之前介绍的技巧中我们介绍了如何将文件系统路径转化为数组,并且通过改变或排除数组的一部分元素创建一个新的路径。
您可以通过将数组转化为 ArrayList 类型来使其变得更简单。现在,您可以非常容易地删除现有的或增加新的路径元素。

这个例子将第一个层文件夹重命名,排除第二层子文件夹,并在第4层子文件夹之后增加一个子文件夹:

$path = 'C:\users\Tobias\Desktop\functions.ps1'

[System.Collections.ArrayList]$array = $path -split '\\'
$array[1] = 'MyUsers'
$array.RemoveAt(2)
$array.Insert(3, 'NewSubFolder')
$array.Insert(4, 'AnotherNewSubFolder')
$array -join '\'

结果路径是:

C:\MyUsers\Desktop\NewSubFolder\AnotherNewSubFolder\functions.ps1

PowerShell 技能连载 - 处理文件系统路径(第2部分)

当您将一个路径转换为数组来操作路径的各个部分时,如果您希望通过固定的数组下标来存取路径的部分,则该方法仅限于子文件夹的数量是固定的情况。

若要操作路径长度不固定的情况,试着利用变量。这个例子将会去除第1层和第2层子文件夹,无论路径有多长:

$path = 'C:\users\Tobias\Desktop\functions.ps1'

$array = $path -split '\\'
$length = $array.Count
$newpath = $array[,0+3..$length]
$newpath -join '\'

请注意提取新路径的数组元素的方法:

$newpath = $array[,0+3..$length]

这行代码取出第1个路径元素(下标为0)和第4个元素以及其之后的所有元素(下标从3开始)。

此处的奥秘是PowerShell支持多个数组下标。表达式 x..y 创建一个范围为x到y的数字型数组,其中x和/或y可以是变量。

当您需要增加单独的下标时,您必须将它们转化为数组,因为只有数组能被添加到数组中。这是为什么代码中下标0写成 ,0 的原因。这样写是为了创建一个只包含0的数组,并且这个数组可以被添加到数字范围的数组,并返回一个包含所有你需要的下标的数组。

PowerShell 技能连载 - 处理文件系统路径(第1部分)

PowerShell允许您存取多个数组元素。通过使用 -help-join,您可以很方便地通过这种方式处理多个文件系统路径。

若要排除第二层和第三层文件夹,试试以下代码:

$path = 'C:\users\Tobias\Desktop\functions.ps1'
$array = $path -split '\\'
$newpath = $array[0,3,4]
$newpath -join '\'

若要重命名第二层子文件夹,试试以下代码:

$path = 'C:\users\Tobias\Desktop\functions.ps1'

$array = $path -split '\\'
$array[2] = 'OtherUser'
$array -join '\'

用PowerShell统计关键词

本来开始打算大干一场的,结果发现区区4行代码搞定了。原来用PowerShell统计关键词这么欢乐啊。

$wordBreakers = ",. ()\\/';-<>_#"
$wordTemplate = '^Pub\w+'
cd D:\Dropbox\workdir\LandiStore\BOCISTDemo\src\Project

$content = (dir *.c -Recurse | % { cat $_} ) -join "`n"
$words = $content.Split($wordBreakers)
$words = $words | ? {$_ -Match $wordTemplate}
#$words | sort -Unique
$words | group | sort count -Descending | select Name, Count

修正文件名/目录名的PowerShell脚本

计划写一系列整理文件用的脚本。例如根据id3来对mp3文件归档、根据exif信息来对照片归档、根据verycd上的资源名称对下载的文件归档……
这时候会遇到一个问题:Windows的文件系统是不允许某些特殊字符,以及设备文件名的。详细的限制请参见:http://zh.wikipedia.org/wiki/%E6%AA%94%E6%A1%88%E5%90%8D%E7%A8%B1。

这个PowerShell脚本帮助你避开这些坑。具体的做法是将特殊字符替换成’.’,对于恰好是设备名称的主文件名或扩展名之前添加’_’。

function Get-ValidFileSystemName
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$FileSystemName
    )

    process{
        $deviceFiles = 'CON', 'PRN', 'AUX', 'CLOCK$', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'
        $fileName = [System.IO.Path]::GetFileNameWithoutExtension($FileSystemName)
        $extension = [System.IO.Path]::GetExtension($FileSystemName)
        if ($extension.StartsWith('.'))
        {
            $extension = $extension.Substring(1)
        }

        if ($deviceFiles -contains $fileName)
        {
            $fileName = "_$fileName"
        }

        if ($deviceFiles -contains $extension)
        {
            $extension = "_$extension"
        }

        if ($extension -eq '')
        {
            $FileSystemName = "$fileName$extension"
        }
        else
        {
            $FileSystemName = "$fileName.$extension"
        }

        $FileSystemName = $FileSystemName -creplace '[\\/|?"*:<>\x00\x1F\t\r\n]', '.'
        return $FileSystemName
    }
}

用脚本批量下载www.cheat-sheets.org中的所有pdf文件

流水不腐,户枢不蠹。虽然批量下载有很多工具能做到,但是为了提高,我们尽量动手编写脚本吧。
http://www.cheat-sheets.org 里有很多好东西,我们把它批量下载下来。

下载的PDF截图

PowerShell代码:

Add-Type -AssemblyName System.Web
$baseUrl = 'http://www.cheat-sheets.org'
$result = Invoke-WebRequest $baseUrl
$result.Links |
    ? {$_.href -Like '*.pdf'} |
    select -ExpandProperty href |
    sort |
    % {
        if ($_ -like '/*')
        {
            $baseUrl + $_
        } else {
            $_
        }
      } |
     % {
        echo "Downloading $_"
        $fileName = $_.Substring($_.LastIndexOf("/") + 1)
        $localFileName = [System.Web.HttpUtility]::UrlDecode($fileName)

        if (Test-Path $localFileName) {
            return
        }
        Invoke-WebRequest -Uri $_ -OutFile $localFileName
        if (Test-Path $localFileName) {
            Unblock-File $localFileName
        }
     }

新手从 0 开始学习 PowerShell 的路线

以下是我个人的PowerShell学习路线,也许可以节省您一些走弯路的时间,供参考。

入门材料

  • 微软虚拟学院 快速入门: PowerShell 3.0 - 有讲座视频、中文字幕、pdf 讲义,轻松起步。我把它们都传到百度云上了,下载地址请参见 PowerShell 微软虚拟学院课程
  • Windows Powershell入门指南(中文)-微软资料.pdf - 篇幅很短,仅 29 页,入门找感觉,一天即可读完。
  • pstips.chm - 中文电子书,篇幅适中,涵盖了语法要点,重点推荐!

速查表

推荐打印出来放案头备用。

  • Windows PowerShell 语言快速参考.rtf - 只有三页纸的速查表(中文)
  • powershell_reference_Apr2010.doc - 只有两页纸的速查表(英文)

中文手册,用于查阅

  • WindowsPowerShellHelp_官方手册.chm - 微软官方,浏览一下有哪些内容,日后备用。

官方网站

Microsoft PowerShell

英文电子书

  • [Windows.PowerShell.Pocket.Reference(2nd,2012.12)].Lee.Holmes.文字版.pdf - 系统学习用,可以一周读完,后几章可跳过,100 来页。
  • [Windows.Powershell.实战(第2版)].(Windows.Powershell.in.Action).Bruce.Payette.文字版.pdf - 经典,深入学习用,900 来页,可以用来当工具书查阅。

邮件列表

  • Power Tips - 右侧有个 Tips via Email,在这儿通过电子邮件订阅,每天会发给你一封短小的邮件。一点一滴学习,内容都很精致。

电子书合集

所有 PowerShell 电子书的合集,自动更新:《PowerShell 电子书合集

个人博客

补充说明

批量更改csdn下载的文件名(UrlDecode)

例如csdn下载的一个文件名字为 %5B大家网%5DWindows.PowerShell应用手册%5Bwww.TopSage.com%5D.pdf,我们通过两行PowerShell脚本把它转化为正常的 [大家网]Windows.PowerShell应用手册[www.TopSage.com].pdf。量大的时候特别好用。

方法如下:

Add-Type -AssemblyName System.Web
dir | % { ren -LiteralPath $_ ([System.Web.HttpUtility]::UrlDecode($_)) }