PowerShell中的类、枚举与测试
立即解锁
发布时间: 2025-08-14 00:55:01 阅读量: 27 订阅数: 25 AIGC 


精通PowerShell脚本编写:自动化与简化任务
### PowerShell中的类、枚举与测试
#### 类与枚举概述
在PowerShell中,枚举对于定义自定义常量值列表非常有用,这些列表可在脚本、函数或模块中使用。枚举中的值既可以按需使用,也可以仅作为名称列表。基于标志的枚举用于管理基于标志的字段,例如`FileSystemRights`枚举就展示了其相关能力。
PowerShell中的类可用于描述任何对象,类包含属性和方法等成员。`hidden`关键字可用于隐藏属性或方法,使其不可见。类继承是处理类的重要部分,一个类可以从另一个类继承属性和方法,从而实现分层的类实现方式,将共享代码放在基础类中。
#### 类与Microsoft Desired State Configuration(DSC)
Microsoft DSC是一种配置管理系统,它以幂等方式配置各个项目,即只有在需要更改时才进行更改。PowerShell中的类很大程度上是因为DSC而存在的。以PowerShell类编写的DSC资源非常简洁,避免了基于脚本的资源中固有的重复,例如基于脚本的资源至少需要重复一个`param`块。
在模块中,基于类的DSC资源必须使用模块清单文档中的`DscResourcesToExport`键显式导出。类必须包含`DscResource`属性,用户期望设置的每个属性都必须有`DscProperty`属性,并且至少有一个属性必须设置为`DscProperty`属性的`Key`属性。类还必须实现`Get`、`Set`和`Test`方法。
以下是一个基本的DSC资源定义示例:
```powershell
enum Ensure {
Absent
Present
}
[DscResource()]
class MyResource {
[DscProperty(Key)]
[Ensure] $Ensure
[MyResource] Get() { return $this }
[void] Set() { }
[bool] Test() { return $true }
}
```
这个资源实现了所有必需的方法,但不执行任何操作。一个好的DSC资源应该专注于一件事,如果一个项目有多种配置选项,通常使用一组相似的资源比使用一个试图完成所有任务的单一资源更好。
#### 创建设置计算机描述的DSC资源
接下来,我们将创建一个设置计算机描述的DSC资源,该资源需要更改单个注册表值。计算机描述通过`HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters`键下的`svrcomment`字符串值进行设置。
以下是资源的框架:
```powershell
enum Ensure {
Absent
Present
}
[DscResource()]
class ComputerDescription {
[DscProperty(Key)]
[Ensure]$Ensure
[DscProperty()]
[string]$Description
hidden $path = 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters'
hidden $valueName = 'svrcomment'
[ComputerDescription] Get() { return $this }
[void] Set() { }
[bool] Test() { return $true }
}
```
其中两个值是隐藏的,它们用于内部使用,用户不应该更改这些值。框架中实现的方法应被以下部分展示的方法替换。
##### 实现Get方法
`Get`方法用于评估资源的当前状态。注册表键会存在,但注册表值可能不正确或不存在。`Get`方法的行为如下:
- 如果值存在,将`Ensure`属性设置为`Present`,并更新`Description`属性的值。
- 如果值不存在,仅将`Ensure`属性设置为`Absent`。
以下是实现这些操作的代码:
```powershell
class ComputerDescription {
[ComputerDescription] Get() {
$key = Get-Item $this.Path
if ($key.GetValueNames() -contains $this.valueName) {
$this.Ensure = 'Present'
$this.Description = $key.GetValue($this.valueName)
} else {
$this.Ensure = 'Absent'
}
return $this
}
}
```
如果添加了本节开头类框架中的属性,就可以调用`Get`方法。调用示例及输出如下:
```powershell
PS> [ComputerDescription]::new().Get() | Format-List
Ensure : Absent
Description :
```
`Get`方法可以返回现有实例(`return $this`),也可以生成新实例,例如返回一个哈希表:
```powershell
class ComputerDescription {
[ComputerDescription] Get() {
$properties = @{}
$key = Get-Item $this.Path
if ($key.GetValueNames() -contains $this.valueName) {
$properties.Ensure = 'Present'
$properties.Description = $key.GetValue($this.valueName)
} else {
$properties.Ensure = 'Absent'
}
return $properties
}
}
```
返回的哈希表会自动转换为类,创建一个新实例。`Get`方法仅在显式调用时使用,`Set`和`Test`方法并不强制使用它。如果`Get`方法创建了一个新实例,它应该返回资源的当前状态。
##### 实现Set方法
`Set`方法用于在需要时进行更改,通常假定`Test`方法已经运行,因此认为需要进行更改。由于资源允许用户确保值存在或不存在,它必须处理值的创建和删除:
```powershell
class ComputerDescription {
[void] Set() {
$commonParams = @{
Path = $this.path
Name = $this.valueName
}
if ($this.Ensure -eq 'Present') {
$newParams = @{
Value = $this.Description
Type = 'String'
Force = $true
}
New-ItemProperty @newParams @commonParams
} else {
$key = Get-Item $this.Path
if ($key.GetValueNames() -contains $this.valueName) {
Remove-ItemProperty @commonParams
}
}
}
}
```
可以通过创建类的实例来调用此方法,运行`Set`方法将尝试更改当前计算机描述值:
```powershell
$resource = [ComputerDescription]@{
Description = 'New description'
}
$resource.Set()
```
`Set`方法没有任何输出,但上述方法除非以管理员身份运行shell,否则将失败。此版本的`Set`方法使用`New-ItemProperty`的`Force`参数覆盖任何同名的现有值,同时也处理值存在但值类型不正确的情况。
##### 实现Test方法
`Test`方法用于确定是否应该运行`Set`方法,DSC在调用`Set`方法之前会先调用`Test`方法,该方法返回一个布尔值。`Test`方法必须执行以下测试来确定此配置项的状态:
- 当`Ensure`为`Present`时,如果值不存在则失败。
- 当`Ensure`为`Present`时,如果值存在但描述与请求的值不匹配则失败。
- 当`Ensure`为`Absent`时,如果值名称存在则失败。
- 否则,通过。
以下是实现这些测试的代码:
```powershell
class ComputerDescription {
[bool] Test() {
$key = Get-Item $this.Path
if ($this.Ensure -eq 'Present') {
if ($key.GetValueNames() -notcontains $this.valueName) {
return $false
}
return $key.GetValue($this.valueName) -eq $this.Description
} else {
return $key.GetValueNames() -notcontains $this.valueName
}
return $true
}
}
```
可以将此方法复制回框架示例中并调用:
```powershell
$resource = [ComputerDescription]@{
Description = 'New description'
}
```
如果描述已经设置,`Test`方法将输出`True`,否则输出`False`:
```powershell
PS> $resource.Test()
False
```
每个方法都必须复制回资源类中。
#### 使用资源
使用此资源需要考虑以下几点:
- 如果使用DSC命令,如`Get-DscResource`和`Invoke-DscResource`,则必须使用Windows PowerShell。注意,PowerShell 7将使用隐式远程处理(兼容性会话)加载`PSDesiredStateConfiguration`。
- 如果直接与类交互,则可以使用两个版本的PowerShell。
完整的`ComputerDescription`类如下:
```powershell
enum Ensu
```
0
0
复制全文
相关推荐










