PowerShell 技能连载 - 查找一个月中的第一天和最后一天

您是否曾需要了解某个月的第一天和最后一天?

以下是一个简单的实现方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
# specify the date you want to examine
# default is today
$date = Get-Date
$year = $date.Year
$month = $date.Month

# create a new DateTime object set to the first day of a given month and year
$startOfMonth = Get-Date -Year $year -Month $month -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0
# add a month and subtract the smallest possible time unit
$endOfMonth = ($startOfMonth).AddMonths(1).AddTicks(-1)

$startOfMonth
$endOfMonth

PowerShell 技能连载 - 在地图上定位您的地理位置

在前一个技能当中,通过 Internet 能知道您的 IP 地址,以及地理位置。您可以获得当前公开 IP 地址的经纬度,代码如下:

1
2
3
4
5
6
$ip = Invoke-RestMethod -Uri http://checkip.amazonaws.com/
$geo = Invoke-RestMethod -Uri "http://geoip.nekudo.com/api/$IP"
$latitude = $geo.Location.Latitude
$longitude = $geo.Location.Longitude

"Lat $latitude Long $longitude"

如果您希望看到它究竟在什么位置,可以将这些信息连到 Google Maps 上:

1
2
3
4
5
6
7
$ip = Invoke-RestMethod -Uri http://checkip.amazonaws.com/
$geo = Invoke-RestMethod -Uri "http://geoip.nekudo.com/api/$IP"
$latitude = $geo.Location.Latitude
$longitude = $geo.Location.Longitude

$url = "https://www.google.com/maps/preview/@$latitude,$longitude,8z"
Start-Process -FilePath $url

这段代码将打开浏览器,导航到 Google Maps,并且在地图上显示当前位置。当前通过 IP 地址定位地理位置还比较粗糙,至少在使用公开地理数据时。

PowerShell 技能连载 - 查找公开 IP 地址

您是否希望了解您当前连接到 Internet 的公开 IP 地址?以下是一行代码:

1
2
#requires -Version 3.0
Invoke-RestMethod -Uri http://checkip.amazonaws.com/

通过这个 IP 地址,您还可以向 Internet 请求您的地理地址:

1
2
3
4
#requires -Version 3.0
$ip = Invoke-RestMethod -Uri http://checkip.amazonaws.com/
Invoke-RestMethod -Uri "http://geoip.nekudo.com/api/$IP" |
Select-Object -ExpandProperty Country

PowerShell 技能连载 - 查找 IP 地址的地理位置

大多数 IP 地址可以用 Web Service 定位到物理地址。以下是一个很简单的函数,能够输入一个 IP 地址并返回它的物理地址:

1
2
3
4
5
6
7
#requires -Version 3.0

function Get-IPLocation([Parameter(Mandatory)]$IPAddress)
{
Invoke-RestMethod -Method Get -Uri "http://geoip.nekudo.com/api/$IPAddress" |
Select-Object -ExpandProperty Country -Property City, IP, Location
}

这个例子能够演示如何用 Select-Object 配合 -Property-ExpandProperty 参数将一些嵌套的属性移到上一层。

让我们查找 Google DNS 服务器位于什么位置:

1
2
3
4
5
6
7
PS C:\> Get-IPLocation -IPAddress 8.8.8.8

name : United States
code : US
city : Mountain View
ip : 8.8.8.8
location : @{accuracy_radius=1000; latitude=37,386; longitude=-122,0838; time_zone=America/Los_Angeles}

And here is how you can resolve any hostname to an IP address, for example, the famous powershellmagazine.com:
以下是如何将任意主机名解析成 IP 地址的代码,例如知名的 powershellmagazine.com:

1
2
PS> [Net.Dns]::GetHostByName('powershellmagazine.com').AddressList.IPAddressToString
104.131.21.239

所以如果您想知道该 IP 地址位于哪里,请加上这段代码:

1
2
3
4
5
6
7
8
PS> Get-IPLocation -IPAddress 104.131.21.239

name : United States
code : US
city : New York
ip : 104.131.21.239
location : @{accuracy_radius=1000; latitude=40,7143; longitude=-74,006;
time_zone=America/New_York}

(of course this is just where the server sits, not Aleksandar or Ravi or all the other fine editors
(当然这只代表了服务器的所在地,而不是 Aleksandar or Ravi 及其它知名编辑的位置

PowerShell 技能连载 - 查找由 DHCP 分配的 IP 地址

从 Windows 8 和 Server 2012 起,随着操作系统一起分发了一些扩展的 PowerShell 模块,用于管理服务器和客户端,例如 Get-NetIPAddress 等 cmdlet。

如果您想获得一个所有由 DHCP 分配的 IP 地址列表,可以试试以下方法:

1
2
3
4
5
#requires -Version 3.0 -Modules NetTCPIP

Get-NetIPAddress |
Where-Object PrefixOrigin -eq dhcp |
Select-Object -ExpandProperty IPAddress

PowerShell 技能连载 - Enum 之周: PowerShell 5 中的枚举

支持 PowerShell 5 以上版本

这周我们将关注枚举类型:它们是什么,以及如何利用它们。

从 PowerShell 5 开始,您可以用 “Enum“创建您自己的枚举类型。通过这种方式,用户可以用可阅读的名字,而不是幻数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#requires -Version  5.0

Enum ComputerType
{
ManagedServer
ManagedClient
Server
Client
}

function Connect-Computer
{
param
(
[ComputerType]
$Type,

[string]
$Name
)

"Computername: $Name Type: $Type"
}

当您运行完这段代码,并调用 “Connect-Computer“ 函数之后,PowerShell 自动为您的枚举值提供智能提示,并且只接受枚举类型里规定的值。

1
2
3
4
PS C:\> Connect-Computer -Type Client -Name Test
Computername: Test Type: Client

PS C:\>

PowerShell 技能连载 - Enum 之周: 快速关闭 Cmdlet 错误提示

这周我们将关注枚举类型:它们是什么,以及如何利用它们。

在前一个技能中,我们学习了枚举类型。这个技能教您如何使用最少的代码关闭 Cmdlet 产生的错误信息。

非管理员账户执行这行代码将产生错误信息,因为您无法存取其他用户的进程信息:

1
PS> Get-Process -FileVersionInfo

由于这个错误是良性的,并且不可避免,您可能会想将它们屏蔽:

1
PS> Get-Process -FileVersionInfo -ErrorAction SilentlyContinue

这对于脚本来说是完美的语法。当您交互式地运行代码时,您完全可以用难看的窍门来缩短关键字的输入,只需要写:

1
PS> Get-Process -FileVersionInfo -ea 0

-ea“ 是 -ErrorAction 参数的别名,而数字 0 相当于 SilentlyContinue 的枚举值。

要查看一个参数的别名,可以使用这样的代码:

1
2
PS> (Get-Command -Name Get-Process).Parameters["ErrorAction"].Aliases
ea

要查看枚举值对应的数字值,首先确定参数的数据类型:

1
2
PS> (Get-Command -Name Get-Process).Parameters["ErrorAction"].ParameterType.FullName
System.Management.Automation.ActionPreference

下一步,将参数转成一个整形:

1
2
PS> [int][System.Management.Automation.ActionPreference]::SilentlyContinue
0

So if you’d like to create a shortcut for the parameter value “Ignore” instead of “SilentlyContinue”, try this:

所以如果您想了解参数值 “Ignore“ 而不是 “SilentlyContinue“,请试验以下代码:

1
2
PS> [int][System.Management.Automation.ActionPreference]::Ignore
4

SilientlyContinue“ 和 “Ignore“ 都禁止了错误的输出,但是 “SilentlyContinue“ 还会将禁止输出的错误信息写入 PowerShell 的 $error 变量中。

从现在开始,您在交互式操作 PowerShell 时可以用这种方式使用 “Ignore“ 禁用错误信息:

1
PS> Get-Process -FileVersionInfo -ea 4

请注意:您也可以在脚本中使用这些快捷方式,但最好不要这么做。脚本中应当按照 PowerShell 的缺省写法,才能清晰易读。

PowerShell 技能连载 - Enum 之周: 理解枚举值

这周我们将关注枚举类型:它们是什么,以及如何利用它们。

在前一个技能中,我们探讨了枚举是如何工作的。您可能还记得我们如何改变控制台的前景色:

1
2
3
4
5
PS> $host.UI.RawUI.ForegroundColor = 'Red'

PS> $host.UI.RawUI.ForegroundColor = 'White'

PS>

这些代码先将前景色改为红色,然后改回白色。用字符串表达的颜色名称隐式地转换为对应的 System.ConsoleColor enumeration 值。

多数枚举只是数字值的一种简易的标签。”Red“ 和 “White“ 实际上是 integer 数值:

1
2
3
4
5
PS> [int][System.ConsoleColor]'Red'
12

PS> [int][System.ConsoleColor]'White'
15

所以如果您知道数字值,您也可以使用它们:

1
2
3
PS> $host.UI.RawUI.ForegroundColor = 12

PS> $host.UI.RawUI.ForegroundColor = 15

当然,很明显地,代码变得很难读懂。不过,还是有一种使用场合。如果您想随机设置您的控制台颜色,您可以使用数值型的值。一共有 16 种控制台颜色,所以这段代码能够用一个随机的背景色和前景色重新为您的控制台着色:

1
2
3
$background, $foreground = 0..15 | Get-Random -Count 2
$host.UI.RawUI.BackgroundColor = $background
$host.UI.RawUI.ForegroundColor = $foreground

PowerShell 技能连载 - Enum 之周: 列出枚举值

这周我们将关注枚举类型:它们是什么,以及如何利用它们。

在前一个技能中我们解释了 PowerShell 如何将字符串转换为枚举值。如果您想知道某个枚举参数可以用接受哪些字符串,请先看一个简单的改变控制台颜色的例子:

1
2
3
4
5
PS> $host.UI.RawUI.ForegroundColor = 'Red'

PS> $host.UI.RawUI.ForegroundColor = 'White'

PS>

这些命令先将前景色改为红色,然后改回白色。

但是您怎么知道控制台支持的颜色名称呢?首先您需要知道 ForegroundColor 的真实数据类型:

1
2
PS> $host.UI.RawUI.ForegroundColor.GetType().FullName
System.ConsoleColor

它的类型是 “System.ConsoleColor“。现在您可以检查它是否确实是一个枚举型:

1
2
PS> $host.UI.RawUI.ForegroundColor.GetType().IsEnum
True

如果它确实是,例如这个例子,您可以列出它所有的值的名称:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PS> [System.Enum]::GetNames([System.ConsoleColor])
Black
DarkBlue
DarkGreen
DarkCyan
DarkRed
DarkMagenta
DarkYellow
Gray
DarkGray
Blue
Green
Cyan
Red
Magenta
Yellow
White

这些值中的每一个值都可以用来设置控制台的前景色。这种方法可以应用在所有接受枚举值的属性或参数上。

同样地,如果您传入了一个和所有枚举值名称都不相同的值,异常信息中也会列出枚举值的名字。

PowerShell 技能连载 - Enum 之周: 枚举的自动转换

这周我们将关注枚举类型:它们是什么,以及如何利用它们。

当一个 Cmdlet 或者方法需要一个枚举值时,PowerShell 能毫无障碍地接受不完整的枚举名称。这个方法不为人知。例如这段代码将控制台的前景色改为灰色:

1
PS> $host.UI.RawUI.ForegroundColor = 'Gray'

这段代码将前景色改为白色:

1
PS> $host.UI.RawUI.ForegroundColor = 'White'

ForegroundColor 属性看上去是字符串类型的,但这并不是真相。它只能接受某些字符串。这个属性的类型实际上不是字符串型。它实际上是一个只接受某些字符串值的枚举型:

1
2
3
4
5
6
7
8
PS> $host.UI.RawUI | Get-Member -Name ForegroundColor


TypeName: System.Management.Automation.Internal.Host.InternalHostRawUserInterface

Name MemberType Definition
---- ---------- ----------
ForegroundColor Property System.ConsoleColor ForegroundColor {get;set;}

该属性实际上是 “System.ConsoleColor“ 类型。当您传入一个类似 “Gray“ 或 “White“ 的字符串时,PowerShell 实际上在后台查询 System.ConsoleColor 类型可选的值,并将传入的字符串做转换。

一个不为人知的事实是:不需要严格的匹配。您可以用这种方法写:

1
2
3
4
5
6
7
8
9
10
11
    PS>  $host.UI.RawUI.ForegroundColor = 'R'

PS> $host.UI.RawUI.ForegroundColor = 'W'
```powershell

这段代码将把控制台的前景色改为红色,然后改回白色。PowerShell 只关心指定的值是否有歧义。如果传入了字符串 "`G`",会发生异常,提示信息是名字冲突。对于灰色,至少要指定 "`Gra`",因为任何比这个短的字符串都和 "`Green`" 相冲突。

为什么这很重要?您必须尽量使用完整的枚举值以提高可读性。只需要记着会自动转换。它帮助您理解为什么这类语句可以工作:

```powershell
Get-Service | Where-Object { $_.Status -eq 'R' }