PowerShell 学习_Part2_Building an inventory tool_1

Tool design guidelines

其实也很简单,就一句话:Do one thing, and do it well

比如:1。Input tools

           2。Functional tools

           3。Output tools

还有要注意的事项:

■ What would be a good name for your tool?
■ What sort of information do you need for each tool? (These might be potential parameters.)
■ How do you think the tool would be run from a command prompt, or what type of data will it write to the pipeline?

Advanced functions, part 1

函数模版:

在这里要说一下Process块:

1. 如果函数只是通过接受参数,没有数据通过管道(pipeline),那么Process只执行一次。

2. 如果调用函数,用管道作为输入,那么Process会处理每一个在管道里的对象。

设计函数:

1. 我们最好要生成一格log文件,可以用来记录失败的情况,如果存在这种情况,可以重新处理失败的情况。

2. 我们要设计的函数功能如下:

     ■ ComputerName—The name of the computer
     ■ OSVersion—The Windows version
     ■ SPVersion—The service pack version
     ■ BIOSSerial—The BIOS serial number
     ■ Manufacturer—The computer’s manufacturer
     ■ Model—The computer’s model description

      第一个我们可以通过参数获得,接下来两个我们通过WMI’s Win32_OperatingSystem class获得;BIOSSerial通过Win32_BIOS;最后的通过Win32
_ComputerSystem class

3. 我们的函数要设计成可以接受多个computername参数,如:Get-SystemInfo –computer one,two,three –errorlog retries.txt

    当然,也可以通过管道,如:Get-Content computers.txt | Get-SystemInfo –errorlog retries.txt

声明参数:

function <name> {
[CmdletBinding()]
param(
[string[]]$ComputerName,
[string]$ErrorLog
)
BEGIN {}
PROCESS {}
END {}
}


测试参数:

function Get-SystemInfo {
[CmdletBinding()]
param(
[string[]]$ComputerName,
[string]$ErrorLog
)
BEGIN {}
PROCESS {
Write-Output $ComputerName
Write-Output $ErrorLog
}
END {}
}
Get-SystemInfo -computername one,two,three -errorlog x.txt
Get-SystemInfo one x.txt


 

编写主要代码:

foreach语句在这里很重要:

function Get-SystemInfo {
[CmdletBinding()]
param(
[string[]]$ComputerName,
[string]$ErrorLog
)
BEGIN {
Write-Output "Log name is $errorlog"
}
PROCESS {
foreach ($computer in $computername) {
Write-Output "computer name is $computer"
}
}
END {}
}
Get-SystemInfo -ComputerName one,two,three -ErrorLog x.txt


 

测试没问题,添加WMI命令:

function Get-SystemInfo {
[CmdletBinding()]
param(
[string[]]$ComputerName,
[string]$ErrorLog
)
BEGIN {
Write-Output "Log name is $errorlog"
}
PROCESS {
foreach ($computer in $computername) {
$os = Get-WmiObject -class Win32_OperatingSystem `
-computerName $computer
$comp = Get-WmiObject -class Win32_ComputerSystem `
-computerName $computer
$bios = Get-WmiObject -class Win32_BIOS `
-computerName $computer
}
}
END {}
}


 

输出用户定义对象:

function Get-SystemInfo {
[CmdletBinding()]
param(
[string[]]$ComputerName,
[string]$ErrorLog
)
BEGIN {
Write-Output "Log name is $errorlog"
}
PROCESS {
foreach ($computer in $computername) {
$os = Get-WmiObject -class Win32_OperatingSystem `
-computerName $computer
$comp = Get-WmiObject -class Win32_ComputerSystem `
-computerName $computer
$bios = Get-WmiObject -class Win32_BIOS `
-computerName $computer
$props = @{'ComputerName'=$computer;
'OSVersion'=$os.version;
'SPVersion'=$os.servicepackmajorversion;
'BIOSSerial'=$bios.serialnumber;
'Manufacturer'=$comp.manufacturer;
'Model'=$comp.model}
$obj = New-Object -TypeName PSObject -Property $props
Write-Output $obj
}
}
END {}
}
Get-SystemInfo -ErrorLog x.txt -ComputerName localhost,localhost


 

说明:

1. 我们创建了一个hash table,并存储在了$Props里。

2. 然后我们用microsoft提供的特殊类型的对象创建了一个新对象,类型为PSObject,然后告诉它用hash table的属性产生新对象$obj

3. 然后用Write-Object输出对象到管道

运行结果:

我们可以把结果输出成我们想要的:

Get-SystemInfo –comp localhost –errorlog x.txt | Export-CSV
Get-SystemInfo –comp localhost –errorlog x.txt | ConvertTo-HTML
Get-SystemInfo –comp localhost –errorlog x.txt | Export-CliXML
Get-SystemInfo –comp localhost –errorlog x.txt | Sort OSVersion
Get-SystemInfo –comp localhost –errorlog x.txt | Format-Table

Advanced functions, part 2

Making parameters mandatory

如何设置参数为强制参数呢,很简单:

添加这个属性:[Parameter(Mandatory=$True)]

注意:

1. 如果同时为参数提供了默认值,那么默认值会被忽略。

2. 因为ComputerName为String[]类型,输入命令后会一直提示输入,两次回车就OK了。

Verbose output

记得我们在前面,因为Begin Block写一个String到pipeline, 所以违背了“一次只输出一个对象”的原则,下面提供一个专门的stream

function Get-SystemInfo {
[CmdletBinding()]
param(
[Parameter(Mandatory=$True)]
[string[]]$ComputerName,
[string]$ErrorLog = 'c:\retry.txt'
)
BEGIN {
Write-Verbose "Error log will be $ErrorLog"
}
PROCESS {
foreach ($computer in $computername) {
Write-Verbose "Querying $computer"
$os = Get-WmiObject -class Win32_OperatingSystem `
-computerName $computer
$comp = Get-WmiObject -class Win32_ComputerSystem `
-computerName $computer
$bios = Get-WmiObject -class Win32_BIOS `
-computerName $computer
$props = @{'ComputerName'=$computer;
'OSVersion'=$os.version;
'SPVersion'=$os.servicepackmajorversion;
'BIOSSerial'=$bios.serialnumber;
'Manufacturer'=$comp.manufacturer;
'Model'=$comp.model}
Write-Verbose "WMI queries complete"
$obj = New-Object -TypeName PSObject -Property $props
Write-Output $obj
}
}
END {}
}

注意

1. 里面的Write-Verbose语句

2. 默认情况下,Write_verbose是不输出的(您运行可能没有看到自己想要的结果),修改运行命令为:Get-SystemInfo -ComputerName localhost–verbose

Parameter aliases

为参数添加别名:在参数上添加属性:[Alias('hostname')],如此运行命令可以:Get-SystemInfo -Host localhost –verbose

Accepting pipeline input

记得在我们function设计的初衷,我们就有提到,-Computername可以从pipeLine接受string,下面我们就来实现,很简单:添加属性:

[Parameter(Mandatory=$True,ValueFromPipeline=$True)]

测试两种模式:

function Get-SystemInfo {
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,ValueFromPipeline=$True)]
[Alias('hostname')]
[string[]]$ComputerName,
[string]$ErrorLog = 'c:\retry.txt'
)
BEGIN {
Write-Verbose "Error log will be $ErrorLog"
}
PROCESS {
Write-Verbose "Beginning PROCESS block"
foreach ($computer in $computername) {
Write-Verbose "Querying $computer"
$os = Get-WmiObject -class Win32_OperatingSystem `
-computerName $computer
$comp = Get-WmiObject -class Win32_ComputerSystem `
-computerName $computer
$bios = Get-WmiObject -class Win32_BIOS `
-computerName $computer
$props = @{'ComputerName'=$computer;
'OSVersion'=$os.version;
'SPVersion'=$os.servicepackmajorversion;
'BIOSSerial'=$bios.serialnumber;
'Manufacturer'=$comp.manufacturer;
'Model'=$comp.model}
Write-Verbose "WMI queries complete"
$obj = New-Object -TypeName PSObject -Property $props
Write-Output $obj
}
}
END {}
}
Write-Host "---- PIPELINE MODE ----"
'localhost','localhost' | Get-SystemInfo -Verbose
Write-Host "---- PARAM MODE ----"
Get-SystemInfo -ComputerName localhost,localhost -Verbose

从输出结果我们可以清楚地看到,pipeline的模式,我们的process运行了两次。

Parameter validation

我们现在的function存在潜在的缺点,我们要一次性查询每台电脑,可能需要很长的时间。所以我们最好加上参数验证,一次只能接受1到10个参数。

[Parameter(Mandatory=$True,ValueFromPipeline=$True)]
[ValidateCount(1,10)]

更新的function如下:

function Get-SystemInfo {
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,ValueFromPipeline=$True)]
[ValidateCount(1,10)]
[Alias('hostname')]
[string[]]$ComputerName,
[string]$ErrorLog = 'c:\retry.txt'
)
BEGIN {
Write-Verbose "Error log will be $ErrorLog"
}
PROCESS {
Write-Verbose "Beginning PROCESS block"
foreach ($computer in $computername) {
Write-Verbose "Querying $computer"
$os = Get-WmiObject -class Win32_OperatingSystem `
-computerName $computer
$comp = Get-WmiObject -class Win32_ComputerSystem `
-computerName $computer
$bios = Get-WmiObject -class Win32_BIOS `
-computerName $computer
$props = @{'ComputerName'=$computer;
'OSVersion'=$os.version;
'SPVersion'=$os.servicepackmajorversion;
'BIOSSerial'=$bios.serialnumber;
'Manufacturer'=$comp.manufacturer;
'Model'=$comp.model}
Write-Verbose "WMI queries complete"
$obj = New-Object -TypeName PSObject -Property $props
Write-Output $obj
}
}
END {}
}
Get-SystemInfo -ComputerName one,two,three,four,five,
six,seven,eight,nine,ten,eleven


 

执行,我们会看到:

“The number of supplied arguments (11) exceeds the maximum number of allowed arguments (10). Specify less than 10 arguments and then try the command again.”的错误信息。

Adding a switch parameter

还有,我们想把ErrorLog参数设置成可选参数:

param(
[Parameter(Mandatory=$True,ValueFromPipeline=$True)]
[ValidateCount(1,10)]
[Alias('hostname')]
[string[]]$ComputerName,
[string]$ErrorLog = 'c:\retry.txt',
[switch]$LogErrors
)


 

添加参数提示信息:

param(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
HelpMessage="Computer name or IP address")]
[ValidateCount(1,10)]
[Alias('hostname')]
[string[]]$ComputerName,
[string]$ErrorLog = 'c:\retry.txt',
[switch]$LogErrors
)


 重要:

There are actually a bunch of other validation attributes that PowerShell understands: Runhelp about_functions_advanced_parameters in the shell to learn all about them.

Comment-based help

function Get-SystemInfo {
<#
.SYNOPSIS
Retrieves key system version and model information
from one to ten computers.
.DESCRIPTION
Get-SystemInfo uses Windows Management Instrumentation
(WMI) to retrieve information from one or more computers.
Specify computers by name or by IP address.
.PARAMETER ComputerName
One or more computer names or IP addresses, up to a maximum
of 10.
.PARAMETER LogErrors
Specify this switch to create a text log file of computers
that could not be queried.
.PARAMETER ErrorLog
When used with -LogErrors, specifies the file path and name
to which failed computer names will be written. Defaults to
C:\Retry.txt.
.EXAMPLE
Get-Content names.txt | Get-SystemInfo
.EXAMPLE
Get-SystemInfo -ComputerName SERVER1,SERVER2
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
HelpMessage="Computer name or IP address")]
[ValidateCount(1,10)]
[Alias('hostname')]
[string[]]$ComputerName,
[string]$ErrorLog = 'c:\retry.txt',
[switch]$LogErrors
)
BEGIN {
Write-Verbose "Error log will be $ErrorLog"
}
PROCESS {
Write-Verbose "Beginning PROCESS block"
foreach ($computer in $computername) {
Write-Verbose "Querying $computer"
$os = Get-WmiObject -class Win32_OperatingSystem `
-computerName $computer
$comp = Get-WmiObject -class Win32_ComputerSystem `
-computerName $computer
Listing 9.1 Adding comment-based help to our function
www.it-ebooks.info
82 CHAPTER 9 Writing help
$bios = Get-WmiObject -class Win32_BIOS `
-computerName $computer
$props = @{'ComputerName'=$computer;
'OSVersion'=$os.version;
'SPVersion'=$os.servicepackmajorversion;
'BIOSSerial'=$bios.serialnumber;
'Manufacturer'=$comp.manufacturer;
'Model'=$comp.model}
Write-Verbose "WMI queries complete"
$obj = New-Object -TypeName PSObject -Property $props
Write-Output $obj
}
}
END {}
}
help Get-SystemInfo -full
发布了138 篇原创文章 · 获赞 11 · 访问量 40万+

猜你喜欢

转载自blog.csdn.net/yjjm1990/article/details/18267425