PowerShell 技能连载 - 进度条定时器

这是一个使用 PowerShell 进度条的简单例子。这段代码显示一个休息倒计时的进度条。只需要调整您希望暂停的秒数即可。您可以使用这个例子在班级或会议中显示休息时间:

1
2
3
4
5
6
7
8
$seconds = 60
1..$seconds |
ForEach-Object { $percent = $_ * 100 / $seconds;

Write-Progress -Activity Break -Status "$($seconds - $_) seconds remaining..." -PercentComplete $percent;

Start-Sleep -Seconds 1
}

PowerShell 技能连载 - 自动生成文档和报告(第 4 部分)

Iain Brighton 创建了一个名为 “PScribo” 的免费的 PowerShell 模块,可以快速地创建文本、HTML 或 Word 格式的文档和报告。

要使用这个模块,只需要运行这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# https://github.com/iainbrighton/PScribo
# help about_document

# create a folder to store generated documents
$OutPath = "c:\temp\out"
$exists = Test-Path -Path $OutPath
if (!$exists) { $null = New-Item -Path $OutPath -ItemType Directory -Force }


Document 'Report' {
Paragraph -Style Heading1 "System Inventory for $env:computername"
Paragraph -Style Heading2 'BIOS Information'
Paragraph 'BIOS details:' -Bold
$bios = Get-WmiObject -Class Win32_BIOS | Out-String
Paragraph $bios.Trim()
} |
Export-Document -Path $OutPath -Format Word,Html,Text

# open the generated documents
explorer $OutPath

在前一个技能中,我们演示了如何通过将对象转换为纯文本的方式,将结果从 cmdlet 添加到文本报告:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# https://github.com/iainbrighton/PScribo
# help about_document

# create a folder to store generated documents
$OutPath = "c:\temp\out"
$exists = Test-Path -Path $OutPath
if (!$exists) { $null = New-Item -Path $OutPath -ItemType Directory -Force }


Document 'Report' {
Paragraph -Style Heading1 "System Inventory for $env:computername"
Paragraph -Style Heading2 'BIOS Information'
Paragraph 'BIOS details:' -Bold
$bios = Get-WmiObject -Class Win32_BIOS | Out-String
Paragraph $bios.Trim()
} |
Export-Document -Path $OutPath -Format Word,Html,Text

# open the generated documents
explorer $OutPath

这是很直接的方法,但是比较土。如果您希望向复杂的表格添加对象结果,请试试这种方法:

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
# https://github.com/iainbrighton/PScribo
# help about_document

# create a folder to store generated documents
$OutPath = "c:\temp\out"
$exists = Test-Path -Path $OutPath
if (!$exists) { $null = New-Item -Path $OutPath -ItemType Directory -Force }

# generate document
Document 'BIOS' {
# get an object with rich information
$info = Get-WmiObject -Class Win32_BIOS

# find out the property names that have actual information
$properties = $info | Get-Member -MemberType *property |
Select-Object -ExpandProperty Name |
Where-Object {

$info.$_ -ne $null -and $info.$_ -ne ''

} |
Sort-Object

# turn each property into a separate object
$infos = $properties | ForEach-Object {
[PSCustomObject]@{
Name = $_
Value = $info.$_
}


}

Paragraph -Style Heading1 "BIOS Information"

# generate a table with one line per property
$infos |
# select the properties to display, and the header texts to use
Table -Columns Name,Value -Headers 'Item','Content' -Width 0

} |
Export-Document -Path $OutPath -Format Word

# open the generated documents
explorer $OutPath

它的基本思想史为每个对象属性创建新的对象,然后以表格的方式显示它们。这段代码显示 BIOS 信息的详细报告。

PowerShell 技能连载 - 自动生成文档和报告(第 4 部分)

Iain Brighton 创建了一个名为 “PScribo” 的免费的 PowerShell 模块,可以快速地创建文本、HTML 或 Word 格式的文档和报告。

要使用这个模块,只需要运行这条命令:

1
Install-Module -Name PScribo -Scope CurrentUser -Force

再之前的技能中,我们介绍了如何生成动态的表格。今天,我们来学习如何根据特定的条件,例如配置错误,高亮某个单元格。

要实现这个目的,我们使用 Set-Style 将格式应用到独立的属性上。以下示例代码选择所有 StartType 的值为 AutomaticStatus 的值是 Stopped 的对象,并将 HighlightedService 应用在 Status 属性上:

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
# https://github.com/iainbrighton/PScribo
# help about_document

# create a folder to store generated documents
$OutPath = "c:\temp\out"
$exists = Test-Path -Path $OutPath
if (!$exists) { $null = New-Item -Path $OutPath -ItemType Directory -Force }

# generate document
Document 'HighlightedReport' {

# get the service data to use:
# generate the service information to use
# (requires PowerShell 5 because prior to PowerShell 5, Get-Service does not supply
# StartType - alternative: use Get-WmiObject -Class Win32_Service, and adjust
# property names)

# IMPORTANT: run this information through Select-Object to get a cloned copy
# of the original objects so that style information can be appended
$services = Get-Service |
Select-Object -Property DisplayName, Status, StartType |
Sort-Object -Property DisplayName

# write heading
Paragraph "Services ($($services.Count) Services found):"

# define style to use for highlighting
Style -Name HighlightedService -Color Red -BackgroundColor Yellow -Bold

# apply a different format to cell "Status" for all objects where
# status is "Stopped" and StartType is "Automatic"
$services |
Where { $_.Status -eq 'Stopped' -and $_.StartType -eq 'Automatic'} |
Set-Style -Property Status -Style HighlightedService

# create the table
$services |
Table -Columns DisplayName,Status,StartType -Headers 'Display Name','Status','Startup Type' -Tabs 1


} |
Export-Document -Path $OutPath -Format Word,Html,Text

# open the generated documents
explorer $OutPath

PowerShell 技能连载 - 自动生成文档和报告(第 3 部分)

Iain Brighton 创建了一个名为 “PScribo” 的免费的 PowerShell 模块,可以快速地创建文本、HTML 或 Word 格式的文档和报告。

要使用这个模块,只需要运行这条命令:

1
Install-Module -Name PScribo -Scope CurrentUser -Force

在前一个技能中,我们介绍了如何生成动态的表格。今天,我们将介绍调整表格和显示任意数据是多么容易。我们从前一个示例中取出服务列表:

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
# https://github.com/iainbrighton/PScribo
# help about_document

# create a folder to store generated documents
$OutPath = "c:\temp\out"
$exists = Test-Path -Path $OutPath
if (!$exists) { $null = New-Item -Path $OutPath -ItemType Directory -Force }

# generate document
Document 'ServiceReport' {
# generate the service information to use
# (requires PowerShell 5 because prior to PowerShell 5, Get-Service does not supply
# StartType - alternative: use Get-WmiObject -Class Win32_Service, and adjust
# property names)
$services = Get-Service | Select-Object -Property DisplayName, Status, StartType

Paragraph -Style Heading1 "System Inventory for $env:computername"
Paragraph -Style Heading2 "Services ($($services.Count) Services found):"

# generate a table with one line per service
$services |
# select the properties to display, and the header texts to use
Table -Columns DisplayName, Status, StartType -Headers 'Service Name','Current State','Startup Type' -Width 0

} |
Export-Document -Path $OutPath -Format Word,Html,Text

# open the generated documents
explorer $OutPath

只需要做少许调整,示例代码将返回所有 ad 用户(假设您安装了 ActiveDirectory 模块并且能操作 AD):

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
# https://github.com/iainbrighton/PScribo
# help about_document

# create a folder to store generated documents
$OutPath = "c:\temp\out"
$exists = Test-Path -Path $OutPath
if (!$exists) { $null = New-Item -Path $OutPath -ItemType Directory -Force }

# generate document
Document 'ADUser' {
# get 40 AD user to illustrate
$user = Get-ADUser -Filter * -ResultSetSize 40 -Properties mail |
Select-Object -Property Name, mail, SID

Paragraph -Style Heading1 "AD User Liste"

# generate a table with one line per user
$user |
# select the properties to display, and the header texts to use
Table -Columns Name, mail, SID -Headers 'Employee','Email','SID' -Width 0

} |
Export-Document -Path $OutPath -Format Word

# open the generated documents
explorer $OutPath

PowerShell 技能连载 - 自动生成文档和报告(第 2 部分)

Iain Brighton 创建了一个名为 “PScribo” 的免费的 PowerShell 模块,可以快速地创建文本、HTML 或 Word 格式的文档和报告。

要使用这个模块,只需要运行这条命令:

1
Install-Module -Name PScribo -Scope CurrentUser -Force

今天,我们将生成一个包含动态表格内容的文档:

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
# https://github.com/iainbrighton/PScribo
# help about_document

# create a folder to store generated documents
$OutPath = "c:\temp\out"
$exists = Test-Path -Path $OutPath
if (!$exists) { $null = New-Item -Path $OutPath -ItemType Directory -Force }

# generate document
Document 'ServiceReport' {
# generate the service information to use
# (requires PowerShell 5 because prior to PowerShell 5, Get-Service does not supply
# StartType - alternative: use Get-WmiObject -Class Win32_Service, and adjust
# property names)
$services = Get-Service | Select-Object -Property DisplayName, Status, StartType

Paragraph -Style Heading1 "System Inventory for $env:computername"
Paragraph -Style Heading2 "Services ($($services.Count) Services found):"

# generate a table with one line per service
$services |
# select the properties to display, and the header texts to use
Table -Columns DisplayName, Status, StartType -Headers 'Service Name','Current State','Startup Type' -Width 0

} |
Export-Document -Path $OutPath -Format Word,Html,Text

# open the generated documents
explorer $OutPath

当您运行这段代码时,它生成三个名为 ServiceReport.docx/html/txt 的文件。如您所见,该报告包含表格形式的服务列表。

PowerShell 技能连载 - 自动生成文档和报告(第 1 部分)

Iain Brighton 创建了一个名为 “PScribo” 的免费的 PowerShell 模块,可以快速地创建文本、HTML 或 Word 格式的文档和报告。

要使用这个模块,只需要运行这条命令:

1
Install-Module -Name PScribo -Scope CurrentUser -Force

下一步,您可以类似这样生成简单的文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# https://github.com/iainbrighton/PScribo
# help about_document

# create a folder to store generated documents
$OutPath = "c:\temp\out"
$exists = Test-Path -Path $OutPath
if (!$exists) { $null = New-Item -Path $OutPath -ItemType Directory -Force }


Document 'Report' {
Paragraph -Style Heading1 "System Inventory for $env:computername"
Paragraph -Style Heading2 'BIOS Information'
Paragraph 'BIOS details:' -Bold
$bios = Get-WmiObject -Class Win32_BIOS | Out-String
Paragraph $bios.Trim()
} |
Export-Document -Path $OutPath -Format Word,Html,Text

# open the generated documents
explorer $OutPath

PowerShell 技能连载 - 从函数中返回富对象(第 2 部分)

当一个函数返回多于四个属性时,PowerShell 将输出结果格式化为列表,否则格式化为表格。在您学习新的方法来影响这种行为之前,请自己验证一下。以下函数返回一个多于 6 个属性的对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Get-TestData
{
# if a function is to return more than one information kind,
# wrap it in a custom object

[PSCustomObject]@{
# wrap anything you'd like to return
ID = 1
Random = Get-Random
Date = Get-Date
Text = 'Hello'
BIOS = Get-WmiObject -Class Win32_BIOS
User = $env:username
}
}

结果是以表格形式呈现:

1
2
3
4
5
6
7
8
9
10
PS> Get-TestData


ID : 1
Random : 147704985
Date : 25.05.2018 13:09:26
Text : Hello
BIOS : \\DESKTOP-7AAMJLF\root\cimv2:Win32_BIOS.Name="1.6.1",SoftwareElementID="1.6.1",SoftwareElementState=3,TargetOperatingSys
tem=0,Version="DELL - 1072009"
User : tobwe

当移除掉一些属性,限制属性个数为 4 个或更少时,PowerShell 输出一个表格:

1
2
3
4
5
PS> Get-TestData

ID Random Text User
-- ------ ---- ----
1 567248729 Hello tobwe

通常,表格的形式比较容易阅读,特别是有多个数据集的时候。当您得到一个 4 个或更少属性的表格时,您可能不是始终希望返回值只有 4 个属性。所以为什么不像类似 cmdlet 一样处理它呢?

Cmdlet 默认情况下只显示属性的一部分:

1
2
3
4
5
PS> Get-Service | Select-Object -First 1

Status Name DisplayName
------ ---- -----------
Running AdobeARMservice Adobe Acrobat Update Service

使用 Select-Object 可以显示地获得所有属性的列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PS> Get-Service | Select-Object -First 1 -Property *


Name : AdobeARMservice
RequiredServices : {}
CanPauseAndContinue : False
CanShutdown : False
CanStop : True
DisplayName : Adobe Acrobat Update Service
DependentServices : {}
MachineName : .
ServiceName : AdobeARMservice
ServicesDependedOn : {}
ServiceHandle :
Status : Running
ServiceType : Win32OwnProcess
StartType : Automatic
Site :
Container

显然,有第一公民和第二公民之分。在您自己的函数中,您可以类似这样定义第一公民:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Get-TestData
{
# define the first-class citizen
[string[]]$visible = 'ID','Date','User'
$info = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',$visible)


[PSCustomObject]@{
# wrap anything you'd like to return
ID = 1
Random = Get-Random
Date = Get-Date
Text = 'Hello'
BIOS = Get-WmiObject -Class Win32_BIOS
User = $env:username
} |
# add the first-class citizen info to your object
Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $info -PassThru

}

现在,您的函数的行为类似 cmdlet,而且您没有定义多于 4 个一等公民,所以缺省情况下得到一个表格的形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PS> Get-TestData

ID Date User
-- ---- ----
1 25.05.2018 13:15:15 tobwe



PS> Get-TestData | Select-Object -Property *


ID : 1
Random : 1298877814
Date : 25.05.2018 13:15:22
Text : Hello
BIOS : \\DESKTOP-7AAMJLF\root\cimv2:Win32_BIOS.Name="1.6.1",SoftwareElementID="1.6.1",SoftwareElementState=3,TargetOperatingSys
tem=0,Version="DELL - 1072009"
User : tobwe

PowerShell 技能连载 - 从函数中返回富对象(第 1 部分)

如果一个 PowerShell 函数需要返回多于一类信息,请确保将这些信息集中到一个富对象中。最简单的实现方式是创建一个类似 [PSCustomObject]@{} 这样的自定义对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Get-TestData
{
# if a function is to return more than one information kind,
# wrap it in a custom object

[PSCustomObject]@{
# wrap anything you'd like to return
ID = 1
Random = Get-Random
Date = Get-Date
Text = 'Hallo'
BIOS = Get-WmiObject -Class Win32_BIOS
User = $env:username
}
}

自定义对象的核心是一个哈希表:每个哈希表键将会转换为一个属性。这个方式的好处是您可以使用哈希表中的变量甚至命令,所以这样要收集您想返回的所有信息,将它合并为一个自描述的对象很容易:

1
2
3
4
5
6
7
8
9
10
PS> Get-TestData


ID : 1
Random : 1794057589
Date : 25.05.2018 13:06:57
Text : Hallo
BIOS : \\DESKTOP-7AAMJLF\root\cimv2:Win32_BIOS.Name="1.6.1",SoftwareElementID="1.6.1",SoftwareElementState=3,TargetOperatingSys
tem=0,Version="DELL - 1072009"
User : tobwe

PowerShell 技能连载 - 在函数内使用持久变量

默认情况下,当一个 PowerShell 函数退出时,它将“忘记”所有的内部变量。然而,有一种办法可以创建持久的内部变量。以下是实现方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# create a script block with internal variables
# that will persist
$c = & {
# define an internal variable that will
# PERSIST and keep its value even though
# the function exits
$a = 0

{
# use the internal variable
$script:a++
"You called me $a times!"
}.GetNewClosure()
}

这段代码创建一个包含内部变量的脚本块。当您多次运行这个脚本块时,计数器会累加:

1
2
3
4
5
6
7
8
PS> & $c
You called me 1 times!

PS> & $c
You called me 2 times!

PS> & $c
You called me 3 times!

然而,脚本内的 $a 变量的作用域既不是 global 也不是 scriptglobal。它的作用域只在脚本块的内部:

1
PS> $a

要将脚本块转换为函数,请加上这段代码:

1
2
3
4
5
6
7
PS> Set-Item -Path function:Test-Function -Value $c

PS> Test-Function
You called me 5 times!

PS> Test-Function
You called me 6 times!