PowerShell 技能连载 - 将 Tick 转换为真实的日期
Active Directory 内部使用 tick (从 1601 年起的百纳秒数)来表示日期和时间。在以前,要将这个大数字转换为人类可读的日期和时间是很困难的。以下是一个很简单的办法:
[DateTime]::FromFileTime(635312826377934727)
类似地,要将一个日期转换为 tick 数,使用以下方法:

PowerShell 技能连载 - 将 Tick 转换为真实的日期
Active Directory 内部使用 tick (从 1601 年起的百纳秒数)来表示日期和时间。在以前,要将这个大数字转换为人类可读的日期和时间是很困难的。以下是一个很简单的办法:
[DateTime]::FromFileTime(635312826377934727)
类似地,要将一个日期转换为 tick 数,使用以下方法:

如果您想记录脚本的运行时间,您可以使用 Measure-Command,但是这个 cmdlet 仅适合诊断目的,并且没有计算输出时间。
另一种方法是创建两个快照,并且在结束时计算时间差。
这段代码将告诉您 Get-Hotfix cmdlet 的执行时间,包括输出数据的时间:
$start = Get-Date
Get-HotFix
$end = Get-Date
Write-Host -ForegroundColor Red ('Total Runtime: ' + ($end - $start).TotalSeconds)
PowerShell 技能连载 - 修正 Excel CSV 的编码
当您将 Microsoft Excel 的数据保存为 CSV 格式时,很不幸的是保存的编码和 Import-Csv 的缺省编码并不匹配。所以当您将 CSV 文件导入 PowerShell 时,无论您指定哪种编码,特殊字符都会变成乱码。
以下是一个我从 Excel 导出的 list.csv 文件,它包含一些特殊字符。如果您使用缺省编码,特殊字符会变成乱码,并且如果您指定了 -Encoding 参数,无论您传什么值,特殊字符都不会显示回原来正常的状态:

当您模拟在这些场景中 Import-Csv 的行为时,它很意外地可以完美处理:

这说明要正确地读取 Excel CSV 文件,您必须显式地指定“缺省”编码(这引出了一个问题:当您未指定编码的时候,缺省使用的是什么编码):

您可以用 Get-Content 来读入整个文本文件。但是,Get-Content 是逐行返回文件的内容,您得到的是一个 string 数组,并且换行符被去掉了。
要一次性读取整个文本文件,从 PowerShell 3.0 开始,您可以使用 -Raw 参数(它还有个好处,能够大大加快读取文件的速度)。
所以通过以下代码您可以获得一个字符串数组,每个元素是一行文本:

Length 属性表示文件的行数。
以下代码一次性读取整个文本文件,返回单个字符串:

这回,Length 属性表示整个文件的字符数,并且读取文件的速度大大提高(虽然也更占内存了)。
那种方法更好?这取决于您要如何使用这些数据。
如果您想以只有您能获取的方式保存敏感数据,您可以使用这个有趣的方法:将明文转换成密文,需要时将密文转换回明文,并将它保存到磁盘中:
$storage = "$env:temp\secretdata.txt"
$mysecret = 'Hello, I am safe.'
$mysecret |
ConvertTo-SecureString -AsPlainText -Force |
ConvertFrom-SecureString |
Out-File -FilePath $storage
当您打开该文件的时候,它读起来像这个样子:

您的秘密被 Windows 自带的数据保护 API(DPAPI) 用您的身份和机器作为密钥加密。所以只有您(或任何以您的身份运行的进程)可以将该密文解密,而且只能在加密时所用的计算机上解密。
要得到明文,请使用这段代码:
$storage = "$env:temp\secretdata.txt"
$secureString = Get-Content -Path $storage |
ConvertTo-SecureString
$ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($secureString)
$mysecret = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr)
$mysecret
它可以正常使用——您可以获得和加密前一模一样的文本。
现在,以其他人的身份试一下。您会发现其他人无法解密该加密文件。而且您在别的机器上也无法解密。
PowerShell 技能连载 - 使用加密文件系统(EFS)来保护密码
如果您必须在脚本中以硬编码的方式包含密码和其它隐私信息(正常情况下应避免使用),那么您还可以通过 EFS(加密文件系统)的方式来保障安全性。加密的脚本只能被加密者读取(和执行),所以只有您在自己的机器上能运行该脚本。
一下是加密一个 PowerShell 脚本的简单方法:
# create some sample script
# replace path with some real-world existing script if you want
# and remove the line that creates the script
$path = "$env:temp\test.ps1"
"Write-Host 'I run only for my master.'" > $path
$file = Get-Item -Path $path
$file.Encrypt()
当您运行这段脚本时,它将在您的临时文件夹中创建一个用 EFS 加密的新的 PowerShell 脚本(如果您见到一条错误提示信息,那么很有可能您机器上的 EFS 不可用或者被禁用了)。
加密之后,该文件在 Windows 资源管理器中呈现绿色,并且只有您能够运行它。别人无法看见源代码。
请注意在许多企业环境中,EFS 系统是通过恢复密钥部署的。指定的维护人员可以通过主密钥解密文件。如果没有主密钥,一旦您丢失了您的 EFS 证书,就连您也无法查看或运行加密的脚本。

微软MVP,这个自1993 年开始在社群上出现的计划(MVP Award Program),目前在全球已经累积超过5,000 人,其中在台湾已经有一百多人了,包括我在内,这个计画现在已经成为以微软技术为主的技术社群(technology community) 中,最高等级的奖励计画,虽然它是由微软主办,但是它是以社群为主的一个计画,对于在社群中活跃但可能不知名的技术高手或是专家们,是一个很具吸引力的计画,因为它除了提供实质性,非金钱价值的奖励以外,还提供了出名的机会(出席研讨会,主持场次,与微软共同推广技术等),所以有很多走微软技术的人都很想拿到它。
不过,据我个人的观察,似乎很多人都 只想拿到它,但却忽略了它背后真正的意义 。
到底什么是MVP ?
微软将MVP 定义为:
微软最有价值专家是微软的一个年度奖项。MVP来自于各行各业,但是他们都有者两个共同点:
在微软,我们视MVP为 最有价值的合作伙伴 。透过奖励,肯定、跟支持这些优秀的技术人员,微软并且和这些重要伙伴保持紧密的联系。
对于社群来说,MVP是一种称号,也是一种地位的象征,它的地位来自于微软官方的认可,但它和MCP Program不同,它是由微软内部针对申请人提交的申请书审查,针对事实来做审核,不像MCP Program被人诟病说用考古题就可以考到一样,它比MCP更具事实上的说服力,而且 当选MVP 大多数的原因是解决问题的数量有一定程度 ,因此解决问题能力强的人,变成MVP的机率就会很高。这也就是为什么MVP会被当成解决问题的专家的原因,毕竟解决问题不像考试那样,考试是在一个给定且没有额外空间可以假设的情况下的解决问题,但在 社群中的问题,多半都和当时的环境相依,且没有固定的答案 ,只有顺利解决问题的才是正解,这和考试有标准答案是差很多的。
因此,MVP除了是一个奖项,称号与名声以外,它也是一种社群责任(community responsibility),针对MVP的主要技术(award technology)而言,MVP必须具备一定水准,且具有低错误率的回答(在社群中)与解决问题(社群与现实环境)的能力,而 这些能力全是厚植于自己的学识与经验,以及对技术的热情。
MVP 所需要的能力
微软在甄选MVP时,会以九种评价目标来评价申请人:
一般而言,被考虑授予Microsoft MVP地位的人员,在这九项甄选条件中至少要具备四项。特别要强调的是,这是一项目标,而不是标准。最后,Microsoft MVP能够就Microsoft技术在群组中展现重大成就并提供重大支援的候选人会优先列入考量。他们为所属社群(尤其是Microsoft新闻群组、网站、清单服务、留言板等线上存取的社群)增添了持续的品质,在了解他们所支援的技术及永远乐于与人分享热忱和专业方面,受到同侪的信任并且被视为领袖。
基于Microsoft的策略、预算限制及方案的公正性,被提名的候选人不可能全部都被授予Microsoft MVP 的身份。换言之,最可能获颁这项殊荣的被提名人,必须在支援社群的影响力方面以明确的评量标准,在「所有」这九项甄选条件中展现足够的实力:例如,在MSNEWS 新闻群组中回应的比例他们自己主持的线上社群(如果有) 服务了多少人他们去年发表演说的免费简报活动(如果有) 有几次、有多少人参与他们志愿主持的使用者群组(如果有) 有哪些直接与间接的影响,等等。到了最后评鉴的时候,每一位候选人都会依据候选人各自的评量标准,以个案方式逐一审核并决定是否授予这项殊荣。这也是每两年一次由各MVP Leads及Microsoft MVP 专案经理与Microsoft 各产品群组及各分公司共同举行的评审程序的一部分。
最后要强调,「MVP方案」的主要目的, 是要透过严格的品质保证专业、公正性和专业精神,在Microsoft社群成员中挑选出「好手中的好手」并且授予这项地位 。 因此,MVP对于技术的要求,便是以能够让社群(不一定是指讨论区)的参与者,认为MVP的申请人是具有一定程度技术水准,并且将他视为技术领导者(technology leads )。除了 技术以外,对于技术的热情也是评价条件之一,这也是MVP每年都要重新申请的关系,技术热情与水准如果能够一直延续甚至提升的话,那连选连任也是很正常的,MVP社群中也有连任十几届的。
如何成为MVP,以及MVP 奖励
如果你认为你具有前段所说的那些条件,那么你可以透过下列管道来报名:
台湾微软每年会以季为单位来开放MVP 甄选的报名,通常是每个的1, 4, 7, 10 四个月,而在当季的MVP 录取名单公布时,随即开始下一季的报名程序,不论你是新科MVP 申请人,还是寻求连任MVP 的申请人,都需要在特定期间报名(连任者会由微软主动通知)。
当选MVP 的申请人,可以得到下列的非金钱价值的奖励:
另外,当选MVP 的申请人都必须要填写一份MVP Non-disclosure agreement (NDA),以确保MVP 具有保密责任,因为微软会和MVP 交流一些未公开的技术情报,这些都是微软的机密,因此需要透过NDA 来建立微软与MVP 间自由沟通的桥梁。
MVP 迷思与责任
外界看MVP 很有名气,但事实上并非如此。
在社群上,MVP总是被外界投以关切的眼光,同时也被赋与较高的技术期望,外界会特别去要求MVP的解答水准,这在社群上很常见,而对于MVP本身而言,也会不自主的对自己的解答产生责任感,并且会不自觉的提升自己的解答水平,让社群可以更能应用解答的内容,来达成自己需要的东西或完成工作,但MVP也是人,也有不会的地方,因此 MVP不该被视为技术之神(真正的神是无所不知的,但MVP也有不会的地方,因此不能相提并论) ,也不该被赋与超出水准太多的期望。MVP本身则也应该要致力保持技术水准,或是扩大自己的涉猎领域,以整合各种技术来提高解答或解决问题的能力。
另一种很常见的错误认知是, MVP被当作微软的员工,其实MVP不是微软的员工 ,这群人是来自社会各个层面,各自拥有不同的专业技术,但都有相同的热情与对于技术的执着,被微软认可授予称号所组成的,我想有可能是因为MVP经常参与微软活动,论坛或是开课,而让外界对MVP有所误解,不过MVP真的不是微软的员工, MVP可没有进入微软公司的智慧卡,而且MVP去微软仍然要走8F的访客入口…。
我个人在MVP 社群中已经待了六年(2004-2009),时间虽然不够长,但也看了不少来申请MVP 的人们,有可以连任很多次的,但也只有一次就没了的,当然也有申请没被录取的,一样米养百样人,各式各样的人都有,而且每个人对MVP 的看法可能也都不相同,不过我个人认为在MVP 这个团体中,有几个共通点:
只是,在这六年之中,我也看过一些MVP 的害群之马,让MVP 的名声受到质疑或是备受批评等,不过这些人其实很少很少,但在社会总关注负面消息的氛围之下,负面的资讯总是容易被关注,所以通常99% 的MVP 贡献,都会被1% 的负面消息所掩盖…
另外,由于MVP的甄选条件使然, 有部份申请人会为了想在申请书上好看一点,便在社群中或是部落格中使用一些奇怪的旁门左道,来炒高自己的评价或是人气指数 ,或者是其他可以被微软认可的条件,然而,这 基本上已违反了MVP间不成文的职业道德规范 ,它也许会让你当选MVP,但本质上这是一种不正当手段,且很容易被MVP团体中的其他成员识破,反而会让自己陷入道德疑虑的泥淖中,想要获得其他MVP在相互支援上的协助的话,会变得非常困难,其中一个原因,便是对你的道德有所质疑。
而且,申请人应该要有一个观念,在微软公布你录取的名单的时候,MVP的责任就已经产生了,申请人在社群,课堂,著作,技术分享与解决问题的各项表现,都会被外界当成评价你,以及MVP团体水准的明确指标,所谓一粒老鼠屎坏了一锅粥,身为MVP团体中的成员之一,应该要有致力维持MVP团体名声以及评价的责任,而不是只想捞到好处,拍拍屁股就走人,甚至于把MVP的评价搞坏后被大家踢出这个团体,业界是很小的,基本的职业水准和职业道德是不可轻忽的。
Test-Path 命令可以检测指定的文件或文件夹是否存在。它对于使用盘符的路径工作正常,但是对于纯 UNC 路径则不可用。
最简单的情况下,这应该返回 $true,并且它的确返回了 $true(假设您没有禁用管理员共享):
$path = '\\127.0.0.1\c$'
Test-Path -Path $path
现在,同样的代码却返回 $false:
Set-Location -Path HKCU:\
$path = '\\127.0.0.1\c$'
Test-Path -Path $path
如果路径不是使用一个盘符,PowerShell 将使用当前路径,如果该路径指向一个非文件系统位置,Test-Path 将在该 provider 的上下文中解析 UNC 路径。由于注册表中没有这个路径,Test-Path 返回 $false。
要让 Test-Path 在 UNC 路径下可靠地工作,请确保您在 UNC 路径之前添加了 FileSystem provider。现在,无论当前位于哪个驱动器路径,结果都是正确的:
Set-Location -Path HKCU:\
$path = 'filesystem::\\127.0.0.1\c$'
Test-Path -Path $path
PowerShell 技能连载 - 启用 PowerShell 远程管理
如果您希望用 PowerShell 远程管理来执行另一台机器上的命令或脚本,那么您需要以完整管理员权限启用目标机器上的远程管理功能:

在客户端,当您在同一个域中并且使用同一个域用户登录时,您不需要做任何额外的事情。
如果您希望通过非 Kerberos 验证方式连接目标计算机时(目标计算机在另一个域中,或您希望使用 IP 地址或非完整限定 DNS 名来连接),那么您需要以管理员权限运行一次以下代码:

将信任的主机设置为“*”之后,PowerShell 将允许您连接任何 IP 或机器名,如果无法用 Kerberos 验证身份,将使用 NTLM 验证。所以该设置不影响哪些人可以和该主机通信(通过防火墙规则设置)。它只是告诉 PowerShell 您将在 Kerberos 不可用的时候使用(更不安全一些的)NTLM 验证方式。NTLM 更不安全一些,因为它无法知道目标计算机是否真的是您想要访问的计算机。Kerberos 认证有相互认证过程,而 NTLM 没有。您的凭据直接被发送到指定的计算机中。假如当一个攻击者有机会用他的机器替换掉目标机器,并且占据了它的 IP 地址,而您使用 NTLM 的话,不会得到任何通知。
注意:如果你打开了远程并设置了信任列表后想关闭远程请运行 Disable-PSRemoting,不禁用远程将可能被人利用。
当远程管理打开以后,您可以通过 Enter-PSSession 访问远程系统,并且您可以用 Invoke-Command 在这些机器上运行命令或脚本。
许多 cmdlet 有内置的远程功能,例如 Get-Service 和 Get-Process 都具有 -ComputerName 参数,同样的还有 Get-WmiObject。
然而,要真正地远程使用这些 cmdlet,还需要一些先决条件。多数使用传统远程技术的 cmdlet 需要在目标机器上启用“远程管理”防火墙规则。它允许 DCOM 通信。还有一些需要目标计算机运行远程注册表服务。
所以在多数场景中,当您拥有目标机器的管理员,并且运行以下命令,则管理员可以通过传统远程 cmdlet 访问目标机器:

注意新版的 Windows 中 netsh firewall 命令可能会被废弃,不过目前仍然可以用。该命令比新版的 netsh advfirewall 命令用起来更简单。