PowerShell 技能连载 - 创建对齐的标题

在 PowerShell 中常常需要创建报表和日志。以下是一个创建漂亮的居中标题的函数。只需要将 $width 改为期望的宽度:

1
2
3
4
5
6
function Show-Header($Text)
{
$Width=80
$padLeft = [int]($width / 2) + ($text.Length / 2)
$text.PadLeft($padLeft, "=").PadRight($Width, "=")
}

以下是执行结果:

1
2
3
4
5
6
7
8
9
10
11
PS> Show-Header Starting
====================================Starting====================================

PS> Show-Header "Processing Input Values"
=============================Processing Input Values============================

PS> Show-Header "Calculating..."
=================================Calculating...=================================

PS> Show-Header "OK"
=======================================OK=======================================

额外的知识点如下:

  • 使用 PadLeft()PadRight() 来填充(扩展)两端,并且是使用您希望的字符来填充空白。

基于这个知识点,现在可以做许多相关的事情,例如创建一个固定宽度的服务器名称列表:

1
2
3
4
5
6
1,4,12,888 | ForEach-Object { 'Server_' + "$_".PadLeft(8, "0") }

Server_00000001
Server_00000004
Server_00000012
Server_00000888

PowerShell 技能连载 - 计算机名、DNS 名称,和 IP 地址

以下是一个单行的代码,返回您计算机的当前 IP 地址和它的完整 DNS 名:

1
2
3
4
5
PS> [System.Net.Dns]::GetHostEntry('')

HostName Aliases AddressList
-------- ------- -----------
DESKTOP-7AAMJLF {} {fe80::532:c4e:c409:b987%18, 192.168.2.129}

要检测一台远程的及其,只需要传入远程计算机的名字来代替空白字符串即可:

1
2
3
4
5
PS> [System.Net.Dns]::GetHostEntry('microsoft.com')

HostName Aliases AddressList
-------- ------- -----------
microsoft.com {} {40.113.200.201, 40.76.4.15, 104.215.148.63, 13.77.161.179...}

如果你只希望获取绑定的 IP 地址列表,请试试以下代码:

1
2
3
4
5
6
PS> [System.Net.Dns]::GetHostEntry('microsoft.com').AddressList.IPAddressToString
40.113.200.201
40.76.4.15
104.215.148.63
13.77.161.179
40.112.72.205

今日知识点:

  • System.Net.Dns 类包含许多有用的 DNS 相关方法。GetHostEntry() 非常有用,因为它既可以接受计算机名称也可以接受 IP 地址,并返回对应的 DNS 名和 IP 地址。
  • 传入空白字符串可以查看本机的设置。

PowerShell 技能连载 - 管理 Windows 授权密钥(第 4 部分)

Slmgr.vbs 是一个用于自动化 Windows 许可证管理的古老的 VBScript。在前一个技能中我们开始直接读取 WMI,跳过 slmgr.vbs。除了已经介绍过的 SoftwareLicensingService 类,还有一个 SoftwareLicensingProduct 拥有许多实例并且获取需要一些时间:

1
Get-WmiObject -Class SoftwareLicensingProduct | Out-GridView

描述列展示了这个类描述了 Windows 中许多不同的可用的许可证类型,只有其中的一部分有获得授权。要获得有用的信息,您需要过滤出正在使用的许可证信息。

-Filter 参数来使用服务端过滤器可以大大加速查询速度。请确保 WMI 只返回 ProductKeyId 非空的实例:

1
Get-WmiObject -Class SoftwareLicensingProduct -Filter 'ProductKeyId != NULL' | Select-Object -Property Name, Description, LicenseStatus, EvaluationEndDate, PartialProductKey, ProductKeyChannel, RemainingAppRearmCount, trustedTime, UseLicenseUrl, ValidationUrl | Out-GridView

结果显示在一个网格视图窗口中,看起来类似这样:

Name                   : Office 16, Office16ProPlusR_Grace edition
Description            : Office 16, RETAIL(Grace) channel
LicenseStatus          : 5
EvaluationEndDate      : 16010101000000.000000-000
PartialProductKey      : XXXXX
ProductKeyChannel      : Retail
RemainingAppRearmCount : 1
trustedTime            : 20190203111404.180000-000
UseLicenseUrl          : https://activation.sls.microsoft.com/SLActivateProduct/SLActivateProduct.asmx?c
                         onfigextension=o14
ValidationUrl          : https://go.microsoft.com/fwlink/?LinkID=187557

Name                   : Office 16, Office16ProPlusMSDNR_Retail edition
Description            : Office 16, RETAIL channel
LicenseStatus          : 1
EvaluationEndDate      : 16010101000000.000000-000
PartialProductKey      : XXXXX
ProductKeyChannel      : Retail
RemainingAppRearmCount : 1
trustedTime            : 20190203111404.622000-000
UseLicenseUrl          : https://activation.sls.microsoft.com/SLActivateProduct/SLActivateProduct.asmx?c
                         onfigextension=o14
ValidationUrl          : https://go.microsoft.com/fwlink/?LinkID=187557

Name                   : Windows(R), Professional edition
Description            : Windows(R) Operating System, OEM_DM channel
LicenseStatus          : 1
EvaluationEndDate      : 16010101000000.000000-000
PartialProductKey      : XXXXX
ProductKeyChannel      : OEM:DM
RemainingAppRearmCount : 1001
trustedTime            : 20190203111405.221000-000
UseLicenseUrl          : https://activation-v2.sls.microsoft.com/SLActivateProduct/SLActivateProduct.asm
                         x?configextension=DM
ValidationUrl          : https://validation-v2.sls.microsoft.com/SLWGA/slwga.asmx

如您所见,日期是以 WMI 格式返回的。用 Get-CimInstance 代替 Get-WmiObject 来获取“真实的”日期对象:

1
PS> Get-CimInstance -Class SoftwareLicensingProduct -Filter 'ProductKeyId != NULL' | Select-Object -Property Name, Description, LicenseStatus, EvaluationEndDate, PartialProductKey, ProductKeyChannel, RemainingAppRearmCount, trustedTime, UseLicenseUrl, ValidationUrl

今日知识点:

  • 通过 SoftwareLicensingProduct WMI 类可以获取到独立的微软产品(包括 Office)许可证信息。
  • 如果您希望 PowerShell 返回可阅读的 DateTime 对象,而不是难阅读的 WMI 日期格式,请使用 Get-CimInstance 来代替 Get-WmiObject

PowerShell 技能连载 - 管理 Windows 授权密钥(第 3 部分)

多数 Windows 许可证激活任务可以通过一个古老的名为 slmgr.vbs 的 VBScript 来实现自动化。不过,用这个工具来获取信息的意义不大。因为 slmgr.vbs 使用的事本地化的字符串,并且将所有数据转换为一个大字符串格式。

一个更好的方法是跳过 slmgr.vbs,而直接查询信息源。要搞清 slmgr.vbs 如何实现这些功能,您可以查看该脚本的源码。请在 PowerShell ISE 中运行这段代码:

1
2
3
4
# get the path to the script file
$Path = Get-Command slmgr.vbs | Select-Object -ExpandProperty Source
# load the script file
$file = $psise.CurrentPowerShellTab.Files.Add($Path)

让我开始将这部分功能转换为 PowerShell。例如 /dlv 参数显示许可证信息:

1
PS> slmgr.vbs /dlv

当您在 VBScript 源码中搜索 “dlv”,能快速找到所有相关的核心代码,有一个名为 GetServiceObject() 的函数,是关于简单 WMI 查询的:

1
g_objWMIService.ExecQuery("SELECT " & strQuery & " FROM " & ServiceClass)

实际上,该脚本展现了关于许可证方面的 WMI 类。从 PowerShell 中您可以方便地查询所有跟它有关的服务信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
PS> Get-WmiObject -Class SoftwareLicensingService


__GENUS : 2
__CLASS : SoftwareLicensingService
__SUPERCLASS :
__DYNASTY : SoftwareLicensingService
__RELPATH : SoftwareLicensingService.Version="10.0.17134.471"
__PROPERTY_COUNT : 38
__DERIVATION : {}
__SERVER : DESKTOP-7AAMJLF
__NAMESPACE : root\cimv2
__PATH : \\DESKTOP-7AAMJLF\root\cimv2:SoftwareLicensingService.Version="10.0.17134.471"
ClientMachineID :
DiscoveredKeyManagementServiceMachineIpAddress :
DiscoveredKeyManagementServiceMachineName :
DiscoveredKeyManagementServiceMachinePort : 0
IsKeyManagementServiceMachine : 0
KeyManagementServiceCurrentCount : 4294967295
KeyManagementServiceDnsPublishing : True
KeyManagementServiceFailedRequests : 4294967295
KeyManagementServiceHostCaching : True
KeyManagementServiceLicensedRequests : 4294967295
KeyManagementServiceListeningPort : 1688
KeyManagementServiceLookupDomain :
KeyManagementServiceLowPriority : False
KeyManagementServiceMachine :
KeyManagementServiceNonGenuineGraceRequests : 4294967295
KeyManagementServiceNotificationRequests : 4294967295
KeyManagementServiceOOBGraceRequests : 4294967295
KeyManagementServiceOOTGraceRequests : 4294967295
KeyManagementServicePort : 1688
KeyManagementServiceProductKeyID :
KeyManagementServiceTotalRequests : 4294967295
KeyManagementServiceUnlicensedRequests : 4294967295
OA2xBiosMarkerMinorVersion : 1
OA2xBiosMarkerStatus : 1
OA3xOriginalProductKey : XXXXXXXXXXXXXXXXXXXXXXXXX
OA3xOriginalProductKeyDescription : [4.0] Professional OEM
OA3xOriginalProductKeyPkPn : [TH]XXXXXXX
PolicyCacheRefreshRequired : 0
RemainingWindowsReArmCount : 1001
RequiredClientCount : 4294967295
TokenActivationAdditionalInfo :
TokenActivationCertificateThumbprint :
TokenActivationGrantNumber : 4294967295
TokenActivationILID :
TokenActivationILVID : 4294967295
Version : 10.0.17134.471
VLActivationInterval : 4294967295
VLRenewalInterval : 4294967295
PSComputerName : DESKTOP-7AAMJLF

slmgr.vbs 不同,您可以以面向对象的格式获得该信息,所以访问具体的项十分容易:

1
2
3
4
5
6
7
8
PS> $all = Get-WmiObject -Class SoftwareLicensingService

PS> $all.OA3xOriginalProductKeyDescription
[4.0] Professional OEM:DM


funcValue 1
}

还有更多内容可以发现。

今日知识点:

  • slmgr.vbs 返回的所有 Windows 许可证信息都来自 WMI。相比于 slmgr.vbs 收到的是难以阅读的文本,您可以直接查询 WMI 并跳过 slmgr.vbs
  • 一个大数据源是 SoftwareLicensingService WMI 类。

PowerShell 技能连载 - 管理 Windows 授权密钥(第 2 部分)

大多数的授权密钥管理任务都可以通过 slmgr 命令完成。

This command is actually an ancient VBScript. To read all of your license settings, for example, try this:
这个命令实际上是一个古老的 VBScript。例如要读取所有许可证设置,请使用以下代码:

1
PS> slmgr.vbs /dlv

这将打开一个独立的窗口,并且显示许多许可证激活细节。在对话框窗口中显示信息对于 PowerShell 和自动化操作帮助不大,而且通过 cscript.exe 运行该 VBScript,可能会失败:

1
2
3
4
5
6
7
8
9
PS> slmgr.vbs /dlv

PS> cscript.exe slmgr.vbs /dlv
Microsoft (R) Windows Script Host, Version 5.812
Copyright (C) Microsoft Corporation. All Rights Reserved.

Script file "C:\Users\tobwe\slmgr.vbs" not found.

PS>

您可以将缺省的 VBS 宿主改为 cscript.exe,但是一个更好的不改变全局设置的做法是:找出这个 VBScript 的完整路径,然后用绝对路径执行它。以下是获得 VBScript 路径的办法:

1
2
PS> Get-Command slmgr.vbs | Select-Object -ExpandProperty Source
C:\WINDOWS\system32\slmgr.vbs

这段代码将读取该信息输出到 PowerShell 控制台:

1
2
3
$Path = Get-Command slmgr.vbs | Select-Object -ExpandProperty Source
$Data = cscript.exe //Nologo $Path /dlv
$Data

不过,$Data 包含了难以阅读的纯文本,而且是本地化的。用这种方法获取许可证和激活信息不太优雅。

由于 slmgr.exe 可以做许多神奇的许可证任务,就如打开它的帮助时看到的那样,让我们在随后的技能中检查它的源码,并且跳过以前的 VBScript 直接获取信息。

1
PS> slmgr /?

今日知识点:

  • Windows 许可证管理通常是通过一个 VBScript slmgr.vbs 来实现。当您通过 “/?“ 调用它,将会获得该命令参数的帮助信息。
  • PowerShell 可以调用 slmgr。要接收执行结果,请通过 cscript.exe 调用它,并且向 slmgr.vbs 提供完整的(绝对)路径。
  • Get-Command 是一个查找系统文件夹(在 $env:PATH 中列出的)中的文件的完整(绝对)路径的方法。

PowerShell 技能连载 - 管理 Windows 许可证密钥(第 1 部分)

我们来看看这个单行的解析 Windows 许可证密钥的迷你系列:

1
2
3
4
PS> $key = (Get-WmiObject -Class SoftwareLicensingService).OA3xOriginalProductKey

PS> $key
KJU8F-XXUZH-UU776-IUZGT-HHGR5

今日知识点:

  • WMI 可以获取许多关于 Windows 许可证和 Windows 许可证状态的信息。
  • Windows 用于许可证管理的一个 WMI 名为 “SoftwareLicensingService”。它可以提供 Windows 许可证号码。
  • 同一个类叶包含了许多额外的信息。请看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
PS> Get-WmiObject -Class SoftwareLicensingService


...
KeyManagementServiceUnlicensedRequests : 4294967295
OA2xBiosMarkerMinorVersion : 1
OA2xBiosMarkerStatus : 1
OA3xOriginalProductKey : XXXXXXXXX
OA3xOriginalProductKeyDescription : [4.0] Professional OEM:DM
OA3xOriginalProductKeyPkPn : [TH]X19-99481
PolicyCacheRefreshRequired : 0
RemainingWindowsReArmCount : 1001
RequiredClientCount : 4294967295
TokenActivationAdditionalInfo :
TokenActivationCertificateThumbprint :
TokenActivationGrantNumber : 4294967295
TokenActivationILID :
TokenActivationILVID : 4294967295
Version : 10.0.17134.471
VLActivationInterval : 4294967295
VLRenewalInterval : 4294967295
PSComputerName : DESKTOP-7AAMJLF

title: “PowerShell 技能连载 - 管理 Windows 许可证密钥”
description: PowerTip of the Day - Managing Windows License Key
categories:

  • powershell
  • tip
    tags:
  • powershell
  • tip
  • powertip
  • series

我们来看看这个单行的解析 Windows 许可证密钥的迷你系列:

1
2
3
4
PS> $key = (Get-WmiObject -Class SoftwareLicensingService).OA3xOriginalProductKey

PS> $key
KJU8F-XXUZH-UU776-IUZGT-HHGR5

今日知识点:

  • WMI 可以获取许多关于 Windows 许可证和 Windows 许可证状态的信息。
  • Windows 用于许可证管理的一个 WMI 名为 “SoftwareLicensingService”。它可以提供 Windows 许可证号码。
  • 同一个类叶包含了许多额外的信息。请看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
PS> Get-WmiObject -Class SoftwareLicensingService


...
KeyManagementServiceUnlicensedRequests : 4294967295
OA2xBiosMarkerMinorVersion : 1
OA2xBiosMarkerStatus : 1
OA3xOriginalProductKey : XXXXXXXXX
OA3xOriginalProductKeyDescription : [4.0] Professional OEM:DM
OA3xOriginalProductKeyPkPn : [TH]X19-99481
PolicyCacheRefreshRequired : 0
RemainingWindowsReArmCount : 1001
RequiredClientCount : 4294967295
TokenActivationAdditionalInfo :
TokenActivationCertificateThumbprint :
TokenActivationGrantNumber : 4294967295
TokenActivationILID :
TokenActivationILVID : 4294967295
Version : 10.0.17134.471
VLActivationInterval : 4294967295
VLRenewalInterval : 4294967295
PSComputerName : DESKTOP-7AAMJLF

PowerShell 技能连载 - 创建 ASCII 艺术

PowerShell 的功能令人惊叹:只需要几行代码,就可以将任意照片和图片转化为一段 ASCII 艺术。PowerShell 只需要加载图片,然后然后逐行逐列扫描它,然后基于每个像素的亮度将每个像素替换为一个 ASCII 字符。

以下是该函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 function Convert-ImageToAsciiArt
{
param(
[Parameter(Mandatory)][String]
$Path,

[ValidateRange(20,20000)]
[int]$MaxWidth=80,

# character height:width ratio
[float]$ratio = 1.5
)

# load drawing functionality
Add-Type -AssemblyName System.Drawing

# characters from dark to light
$characters = '$#H&@*+;:-,. '.ToCharArray()
$c = $characters.count

# load image and get image size
$image = [Drawing.Image]::FromFile($path)
[int]$maxheight = $image.Height / ($image.Width / $maxwidth)/ $ratio

# paint image on a bitmap with the desired size
$bitmap = new-object Drawing.Bitmap($image,$maxwidth,$maxheight)


# use a string builder to store the characters
[System.Text.StringBuilder]$sb = ""

# take each pixel line...
for ([int]$y=0; $y -lt $bitmap.Height; $y++){
# take each pixel column...
for ([int]$x=0; $x -lt $bitmap.Width; $x++){
# examine pixel
$color = $bitmap.GetPixel($x,$y)
$brightness = $color.GetBrightness()
# choose the character that best matches the
# pixel brightness
[int]$offset = [Math]::Floor($brightness*$c)
$ch = $characters[$offset]
if (-not $ch){ $ch = $characters[-1] }
# add character to line
$null = $sb.Append($ch)
}
# add a new line
$null = $sb.AppendLine()
}

# clean up and return string
$image.Dispose()
$sb.ToString()
}

以下是它的使用方法:

1
2
3
4
5
6
7
8
$Path = "C:\Users\Tobias\Desktop\Somepic.jpg"
$OutPath = "$env:temp\asciiart.txt"

Convert-ImageToAsciiArt -Path $Path -MaxWidth 150 |
Set-Content -Path $OutPath -Encoding UTF8


Invoke-Item -Path $OutPath

请确保调整了代码中的路径。将会在缺省的文本编辑器中打开 ASCII 艺术。请确保禁用了换行,选择一个等宽的字体和一个足够小的字号!

                                         ;@&&&&&&@&&&&@+-
                                       :@&&&&&&&&&&&&&&&&&&:.
                                     ,&&&&&&&&&&&&&&&&&&&&&&&&&&*
                                  -@&&&&&&&&&&&HHHHHH&&&&&&&&&&&&&*
                               :&&&&&&&&&&&&H&&&&&&&&&&&&&&&&&&&&&&&@
                              *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&,
                             :&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&-
                            *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*
                           &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
                          @&&&&&&&&H&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&-
                         &&&&&&&&H&&&@;:+&&&&&&&*-....,:@&&&&&&&&&&&&&&&&&&&@
                        &&&&&&&&H&&;........................*&&&&&&&H&&&&&&&&&.
                      .&&&&&&&&&H;...........................&&&&&&&&H&&&&&&&&&-
                     ;&&&&&&&&&&:............................@@&&&&&&H&&&&&&&&&&
                    &&&&&&&&&&&.+...........................-.;&&&H&&H&&&&&&&&&&@
                   *&H&&&&&&&&;;..............................+@+&&HH&&&&&&&&&&&&
                   ;&H&&&&&&&&................................@*.&&&H&&&&&&&&&&&&:
                   :&H&&&&&&&*...............................:*..&H&&&&&&&&&&&&&&@
                   ,&&H&&&@&@...................................,&&&&&&&&&&&&&&&&&,
                   ,&&&&&&:+....................................+*.;:&&&&&&&&&&&&&&
                   +&&&&&&............................................@*@+&&&&&&&&&,
                   &&&&&&;............................................,-..-+&&&&&&&
                  :&&&&&@-...................................................:&&&&&,
                  &&&&&&&.....................................................&&&&&-
                  &&&&&&+.....................................................&&&&&,,
                  :&&&&&;.....................................................&&&H&
                   &&&&&;.......................................,.,...........&&&&H&@
                  *-&&&&:...*&&&&&&&&&&&&&@*,.............-*&&&&&&&&&&&&:.....@&&&&+
                    &&&&:.+&&HHHHHHHHHHHHH&&&&..........+&&&&HHHHHHHHHHHHH*...+&&&&@
                   ,###H*+;;:,...........-;*&&##########&&&*:..........:;*@:;*&###H:
                   :##H*.......................#@;---+#;.......................@###.
                  ,@###+............+HH&+.....-&......-*......;&H&*............&##:.
                   ,&&#-...........HHH&+H;....@;......,#.....@HHH;H@...........HH&-.
                   ..;#,...........HHHHHH+....#........H,....&HHHHH&..........-#&:-
                   ...H*...........-;;;;;....-H........;@....,;;;;;,..........;#&..
                   ...&#.....................#-.........#.....................&H*..
                   ...:H&........,.........-#@..........-#;..........,,......:#&,..
                    ...-,&###&+::-,,::+&###+......  ......-###H*:::,,::+@####,....
                    ..........,,,,,,,,...........   ............,,,,,,,,..........
                     ............................   ..............................
                     ............................   .............................
                      .....................,.....   ............................
                       ....................,.....   .......,...................
                         ..................,,,...   .......,.................
                          ......................,.  ..,......................
                          ........................,,,.......................
                          ..................................................
                           .................................................
                           .............,-..................--.............
                            ...............--,,-----:-,. --...............
                             ..................,,----,,...................
                              ...........................................
                               .........................................
                                ......................................
                                 ....................................
                                   ................................
                                    ..............................
                                     .,,,,,,,,,,,,,,,,,,,,,,,,,,
                                   ,&...,,,,,,,,,,,,,,,,,,,,,,...@,
                                &HHH......,,,,,,,,,,,,,,,,,,.....-HHH&
                            :HHHHHHH&.........,,,,,,,,,,,........HHHHHHHH;
                         *HHHHHHHHHHHH+........................*HHHHHHHHHHHH@
                      -HHHHHHHHHHHHHHHHH&;..................;&HHHHHHHHHHHHHHHHH,
                     HHHHHHHHHHHHHHHHHHHHHHHH&*;:---::;*&HHHHHHHHHHHHHHHHHHHHHHH&
                    HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

这儿有一个很酷的优化技巧:在 Convert-ImageToAsciiArt 函数中,请注意 $characters。它是一个包含 ASCII 艺术中使用的字符的字符串,而这些字符是按亮度降序排列的。对于黑白作品,可以使用:

1
$characters = [char]0x2588, ' '

PowerShell 技能连载 - 验证本地用户账户密码

在前一个技能VS,我们通过 Active Directory 来验证用户账户密码。同样的,对于本地账户也可以。PowerShell 代码可以使用本地账户密码来管理对脚本的存取,或部分限制脚本的功能。当然,您也可以用以下代码来创建自己的基本的密码穷举工具。

缺省情况下,以下代码使用您当前的用户名。请确保 $UserName 是某个本地账户的用户名:

1
2
3
4
5
6
7
8
9
# specify local user name and password to test
$UserName = $env:USERNAME
$Password = Read-Host -Prompt "Enter password to test"

# test password
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$type = [DirectoryServices.AccountManagement.ContextType]::Machine
$PrincipalContext = [DirectoryServices.AccountManagement.PrincipalContext]::new($type)
$PrincipalContext.ValidateCredentials($UserName,$Password)

今日的知识点:

  • PowerShell 可以请求本地的 Windows 用户数据库来验证密码。通过这种方式,您可以使用 Windows 维护的密码来决定一个脚本是否允许执行,或允许某个用户执行哪一部分。
  • 请注意向用户询问密码是一种不安全的做法,因为他们不知道密码将会被用在什么地方。

PowerShell 技能连载 - 校验域账户密码

PowerShell 可以轻松地校验一个域账号的密码。换句话说,您可以为 Active Directory 维护的密码绑定一个脚本逻辑。

以下是将密码发送到 AD 并获取回一个 Boolean 值的代码:如果密码正确,返回 $true,否则返回 $false

1
2
3
4
5
6
7
8
9
10
# specify user name and user domain
$UserDomain = $env:USERDOMAIN
$UserName = $env:USERNAME
$Password = Read-Host -Prompt "Enter password to test"

# test password
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$PrincipalContext = [System.DirectoryServices.AccountManagement.PrincipalContext]::new($ContextType, $UserDomain)
$PrincipalContext.ValidateCredentials($UserName,$Password)

请注意这段代码需要 Active Directory 环境,并且不支持本地账号。缺省情况下,它使用您当前账号的详细信息。请根据实际情况调整 $UserDomain$UserName$Password 变量。也请注意 ValidateCredentials() 检查的是明文字符串密码。请谨慎处理并且不要在脚本存储明文密码。同时,不要要求用户以明文输入密码。

今日知识点:

  • PowerShell 可以轻松地连接到 Active Directory 并进行密码验证。

PowerShell 技能连载 - 等待服务状态变化

当您启动或停止一个服务时,可能需要一些时间才能确保服务进入指定的状态——或者它当然可能会失败。当您使用 Stop-Service 时,PowerShell 将等待该服务状态已确认。如果您希望获得其它地方初始化的服务响应,以下是一段监听代码,它将会暂停 PowerShell 直到服务变为指定的状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
# wait 5 seconds for spooler service to stop
$serviceToMonitor = Get-Service -Name Spooler
$desiredStatus = [System.ServiceProcess.ServiceControllerStatus]::Stopped
$maxTimeout = New-TimeSpan -Seconds 5

try
{
$serviceToMonitor.WaitForStatus($desiredStatus, $maxTimeout)
}
catch [System.ServiceProcess.TimeoutException]
{
Write-Warning 'Service did not reach desired status within timeframe.'
}

您可以使用这段代码来响应由外部系统触发的服务改变,或者当您要求服务状态更改后做二次确认。

今日的知识点:

  • 您从 cmdlet 获得的多数对象(例如 Get-Service)有许多有用的方法。所有服务对象都有一个 WaitForStatus 方法。在我们的例子中演示了如何使用它。
  • 要发现隐藏在对象中的其它方法,请使用以下代码:
1
2
3
4
5
# get some object
$objects = Get-Process

# dump the methods
$objects | Get-Member -MemberType *method* | Select-Object -Property Name, Definition