PowerShell 技能连载 - 产生多个返回值

适用于所有 PowerShell 版本

如果一个 PowerShell 函数需要产生多个返回信息,最佳的实践方式是返回多个对象,然后将信息分别存储在对象的各个属性中。

以下是一个有趣的例外情况,它在某些场景中较为适用。尽管返回多个信息就可以了,并且要确保将结果赋值给多个变量:

function Get-MultipleData
{
  Get-Date
  'Hello'
  1+4
}

$date, $text, $result = Get-MultipleData

"The date is $date"
"The text was $text"
"The result is $result"

这个测试函数产生 3 段信息,然后将结果存储在 3 个不同的变量中。

Excel 列号和数字互相转换

Excel 的列号是采用“A”、“B”……“Z”、“AA”、“AB”……的方式编号。但是我们在自动化操作中,往往希望用数字作为列号。我们可以用 PowerShell 来实现 Excel 的列号和数字之间的互相转换。

需求归纳

Excel 列号 -> 数字

A   1
AB  28
AC  29

数字 -> Excel 列号

1   A
2   B
24  Y
26  Z
27  AA
28  AB

算法分析

  • Excel 列号 -> 数字
    • 用 ASCII 编码对输入的字符串解码,得到一个数字型数组。
    • 用 26 进制对数组进行处理(逐位 *= 26,然后累加)。
  • 数字 -> Excel 列号
    • 用 26 进制对数字进行处理(不断地 /= 26,取余数),得到数字型数组。
    • 将数字型数组顺序颠倒。
    • 用 ASCII 编码对数字型数组编码,得到 Excel 风格的列号。

源代码

转换函数:

function ConvertFrom-ExcelColumn ($column) {
    $result = 0
    $ids = [System.Text.Encoding]::ASCII.GetBytes($column) | foreach {
        $result = $result * 26 + $_ - 64
    }
    return $result
}

function ConvertTo-ExcelColumn ($number) {
    $ids = while ($number -gt 0) {
        ($number - 1) % 26 + 1 + 64
        $number = [math]::Truncate(($number - 1) / 26)
    }

    [array]::Reverse($ids)
    return [System.Text.Encoding]::ASCII.GetString([array]$ids)
}

测试代码:

echo "A`t$(ConvertFrom-ExcelColumn A)"
echo "AB`t$(ConvertFrom-ExcelColumn AB)"
echo "AC`t$(ConvertFrom-ExcelColumn AC)"

echo ''

@(1..2) + @(25..28) | foreach {
    echo "$_`t$(ConvertTo-ExcelColumn $_)"
}

执行结果:

A   1
AB  28
AC  29

1   A
2   B
25  Y
26  Z
27  AA
28  AB

您也可以在这里下载完整的脚本。

用 PowerShell 快速查看 PATH 环境变量

我们常常需要查看 PATH 环境变量里是否有我们需要的路径。通常的做法是:

  1. 依次打开 系统属性 / 高级 / 环境变量。
  2. 分别在“用户变量”和“系统变量”列表框中双击 PATH 条目。
  3. 在“变量值”窄小的文本框中检视 PATH 变量的值。
  4. 往往不得不把变量值复制粘贴到记事本中,再利用搜索功能来查找。

利用 PowerShell,可以告别以上笨拙的步骤:

PS > (type env:path) -split ';'

这样就可以看到一个完美分割过的列表了。当然,利用 PowerShell 强大的查询功能,还可以进一步节省眼力。例如我们要查询所有包含“_bin_”的路径:

PS > (type env:path) -split ';' | sls bin

C:\PROGRAM FILES (X86)\JAVA\JDK1.7.0_45\JRE\BIN
C:\PROGRAM FILES (X86)\INTEL\OPENCL SDK\2.0\BIN\X86
C:\PROGRAM FILES (X86)\INTEL\OPENCL SDK\2.0\BIN\X64
C:\PROGRAM FILES\MICROSOFT SQL SERVER\110\TOOLS\BINN\
D:\greensoft\UnxUtils\usr\local\wbin\
C:\Program Files\Microsoft SQL Server\120\Tools\Binn\
C:\Program Files\TortoiseGit\bin
C:\Chocolatey\bin
c:\Program Files\MongoDB 2.6 Standard\bin

PowerShell 技能连载 - 编辑“hosts”文件

适用于所有 PowerShell 版本

如果您常常需要修改“hosts”文件,那么手工用提升权限的记事本实例来打开文件是相当乏味的事情。这是因为该文件只能被 Administrators 用户修改,所以普通的记事本实例无法修改它。

以下是一段您可以直接使用,或者调整一下用来打开任何需要提升权限的程序的脚本。

function Show-HostsFile
{
  $Path = "$env:windir\system32\drivers\etc\hosts"
  Start-Process -FilePath notepad -ArgumentList $Path -Verb runas
}

打包 node 应用程序为单一文件可执行程序

解决方案

  • crcn/nexe - create a single executable out of your node.js apps。支持多个平台,似乎靠谱。
  • areve/node2exe - 只支持 Windows,用 copy /b 合并多个文件。
  • appjs/appjs - 已过期,被 node-webkit 替代。
  • rogerwang/node-webkit - Call all Node.js modules directly from DOM and enable a new way of writing applications with all Web technologies. 带图形界面的不二选择。
  • creationix/topcube - Gives node developers a way to have a desktop GUI to their node servers using HTML5 + CSS3 as the GUI platform.

讨论

Hexo 博客学习路线

Hexo 是一个快速、便捷、强大的博客框架,通过 Node.js 技术构建。

  • 如果你对默认配置满意,只需几个命令便可秒搭一个hexo。
  • 如果你跟我一样喜欢折腾下,30分钟也足够个性化。
  • 如果你过于喜欢折腾,可以折腾个把星期,尽情的玩。

HEXO

官方链接

教程

云空间

工具

我制作了一系列脚本,用于整理博客文章、抓取外部图片、批处理生成发布等,请参见 victorwoo/victorwoo - GitCafe

PowerShell 技能连载 - 请注意 UNC 路径!

适用于所有 PowerShell 版本

许多 cmdlet 可以处理 UNC 路径,但是使用 UNC 路径会导致很多古怪的情况。请看以下:

PS> Test-Path -Path \\127.0.0.1\c$
True

这段代码返回了 true,该 UNC 路径存在。现在将当前驱动器变为一个非文件系统驱动器,然后再次实验:

PS> cd hkcu:\

PS> Test-Path -Path \\127.0.0.1\c$
False

同样的路径现在返回了 false。这是因为 UNC 路径并不包含驱动器号,而 PowerShell 需要驱动器号来指定正确的提供器。如果一个路径不包含驱动器号,那么 PowerShell 假设使用当前驱动器的提供器。所以如果您将当前的目录改为注册表,PowerShell 尝试在那儿查找 UNC 路径,那么就会失败。

更糟糕的是,出于某些未知的原因,但您用 net use 来映射驱动器时,PowerShell 在使用 cmdlet 来访问驱动器时可能会也可能不会产生混淆。

解决方案十分简单:当您用 cmdlet 访问 UNC 时,始终在 UNC 路径前面加上正确的提供器名称。这将消除该问题:

PS> Test-Path -Path FileSystem::\\127.0.0.1\c$
True

PS> cd hkcu:\

PS> Test-Path -Path \\127.0.0.1\c$
False

PS> Test-Path -Path FileSystem::\\127.0.0.1\c$
True

如果您遇到了 net use 产生的问题,也可以使用同样的办法,在路径前面加上 “FileSystem::。该问题可以立刻得到解决。

用 PowerShell 创建一个 HTTP 服务器

用 PowerShell 创建一个 HTTP 服务器其实非常简单,只要 0.8 KB 的代码就搞定了。只要将以下代码保存成 httpd.ps1 并在您的 www 资源目录里执行即可:

param($Root=".", $Port=8080, $HostName="localhost")

pushd $Root
$Root = pwd

$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add("http://$HostName`:$Port/")
$listener.Start()

echo ("Start {0} at `"$Root`"" -f ($listener.Prefixes | select -f 1))
echo "Enter Ctrl + C to stop."

while ($true) {
    $context = $listener.GetContext()

    $url = $context.Request.Url.LocalPath.TrimStart('/')
    $res = $context.Response
    $path = Join-Path $Root ($url -replace "/","\")
    echo $path

    if ((Test-Path $path -PathType Leaf) -eq $true) {
        $content = [IO.File]::ReadAllBytes($path)
        $res.OutputStream.Write($content, 0, $content.Length)
    }
    else {
        $res.StatusCode = 404
    }
    $res.Close()
}

您也可以从这儿下载完整的文件。

这是从一个开源项目中看到的:
MarkdownPresenter/httpd.ps1 at master · jsakamoto/MarkdownPresenter

从命令行运行 PowerShell

从命令行运行 PowerShell 命令最精炼的代码:

@powershell -nop -ex unrestricted -c "Get-ChildItem"

最后一个参数可以换成别的命令。另外,从命令行运行 .ps1 脚本的方式是:

@powershell -nop -ex unrestricted .\something.ps1

markdown 学习路线

Markdown 是一种轻量级标记语言,创始人为约翰·格鲁伯(John Gruber)。它允许人们“使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档”。这种语言吸收了很多在电子邮件中已有的纯文本标记的特性。

markdown

介绍

规范

Markdown 的基本语法较为简单,所以多家衍生出不同的扩展版本。其中由于 GitHub 网站的流行,导致 Markdown 的 GitHub 扩展版本(简称 GFM)较为流行。

以下是基本语法和各个扩展版本的语法文档原始链接:

编辑器

基于 .NET 开发,只用于 Windows,功能较齐全。GFM 风格离线编辑要收费。

MarkdownPad Screenshot

文化