Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Ресурсы DSC на основе классов предоставляют упрощенную реализацию ресурсов DSC для управления параметрами системы. В этой статье объясняется их структура и требования.
Структура ресурса DSC на основе класса
Ресурс DSC на основе класса определяется как класс PowerShell в файле модуля (.psm1
). Ресурс DSC на основе класса не имеет особых требований к определенному ресурсу. Его можно определить:
- В корневом модуле, например
MyModule.psm1
- Во вложенном модуле, например
MyDscResource.psm1
Независимо от того, где определен ресурс DSC, ресурс DSC должен быть указан в свойстве DscResourcesToExport файла манифеста модуля (.psd1
). Командлет Get-DscResource, динамический ключевое слово [Import-DSCResource] и сам DSC при компиляции конфигурации DSC завершится ошибкой, если ресурс DSC не указан в манифесте.
Дополнительные сведения о создании манифеста модуля см. в разделе New-ModuleManifest. Дополнительные сведения о параметрах манифеста модуля см. в разделе about_Module_Manifests.
Ресурс DSC на основе класса должен:
- Используйте атрибут DscResource .
- Объявите одно или несколько свойств с помощью атрибута DscProperty . По крайней мере одно из свойств должно быть свойством Key .
- Реализуйте методы
Get()
,Test()
иSet()
. - Определите конструктор по умолчанию, если он определяет альтернативные конструкторы.
Атрибут DscResource
Определение класса должно иметь атрибут DscResource . Этот атрибут указывает, что класс определяет ресурс DSC.
Чтобы добавить атрибут DscResource в класс, объявите его в строке непосредственно перед определением класса.
[DscResource()]
class MyDscResource {
}
Наряду с определением класса как ресурса DSC атрибут DscResource применяет проверку времени синтаксического анализа к ресурсу DSC на основе класса. PowerShell вызывает ошибку синтаксического анализа для определения ресурса DSC на основе класса в следующих случаях:
- Один или несколько
Get()
методов ,Test()
иSet()
неправильно определены или отсутствуют - Класс не имеет по крайней мере одного свойства Key
- Класс определяет конструктор, не используемый по умолчанию, без определения конструктора по умолчанию.
Атрибут DscResource также можно указать с помощью свойства RunAsCredential , чтобы указать поведение ресурса DSC на основе класса при использовании свойства PsDscRunAsCredential :
-
Optional
— Пользователь может использовать свойство PsDscRunAsCredential с этим ресурсом DSC. Это поведение по умолчанию. Это поведение также можно указать какDefault
вместоOptional
. -
NotSupported
— Пользователь не может использовать свойство PsDscRunAsCredential с этим ресурсом DSC. -
Mandatory
— Пользователь должен использовать свойство PsDscRunAsCredential с этим ресурсом DSC.
Примечание
Хотя вы можете задать свойство RunAsCredential для ресурса DSC на основе класса, оно не оказывает никакого влияния при использовании с DSC версии 2.0 и более поздних версий. Свойство PsDscRunAsCredential поддерживается только в DSC версии 1.1 и более ранних версиях. Если вы пишете ресурс DSC на основе класса и поддерживаете его в DSC версии 1.1, указание этого свойства в атрибуте DscResource обеспечивает некоторую ясность и улучшенный пользовательский интерфейс для этого сценария.
Свойства ресурса DSC на основе классов
Схема ресурса DSC на основе класса определяется свойствами класса . Чтобы свойство было распознано как часть схемы, оно должно иметь атрибут DscProperty .
Определение DscProperty определяет, как DSC обрабатывает это свойство:
-
[DscProperty(Key)]
— указывает, что это свойство однозначно идентифицирует экземпляр этого ресурса DSC. Каждый ресурс DSC должен иметь по крайней мере одно свойство Key . Если ресурс DSC имеет несколько свойств Key , эти свойства используются вместе для уникальной идентификации экземпляра ресурса DSC. Если какие-либо свойства Key ресурса DSC не указаны при использованииInvoke-DscResource
, командлет выдает ошибку. Если при создании конфигурации DSC не указаны какие-либо свойства ключа , компиляция конфигурации вызывает ошибку. -
[DscProperty(Mandatory)]
— указывает, что при использовании этого ресурса DSC необходимо указать свойство . Если при использованииInvoke-DscResource
не указаны какие-либо обязательные свойства ресурса DSC , командлет выдает ошибку. Если при создании конфигурации DSC не указаны какие-либо обязательные свойства, компиляция конфигурации вызывает ошибку. -
[DscProperty(NotConfigurable)]
— указывает, что свойство имеет значение ReadOnly. Этот параметр не является управляемым параметром этого ресурса DSC, но будет содержать значение послеGet()
вызова метода ресурса DSC. -
[DscProperty()]
— указывает, что свойство является настраиваемым параметром этого ресурса DSC. Указание этого свойства является необязательным при использованииInvoke-DscResource
или создании конфигурации DSC.
Как и все свойства класса PowerShell, свойства ресурса DSC на основе класса должны указывать тип. Этот тип используется для проверки указанного параметра при вызове Invoke-DscResource
или компиляции конфигурации DSC.
Рассмотрим этот фрагмент определения ресурса DSC на MyDscResource
основе класса:
[DscResource()]
class MyDscResource {
[DscProperty(Key)]
[string] $Path
[DscProperty(Mandatory)]
[hashtable]$Settings
[DscProperty(NotConfigurable)]
[datetime] $LastModified
[DscProperty()]
[string] $Format = 'YAML'
}
Он определяет четыре свойства:
- Path является свойством Key для ресурса DSC и ожидает получения строки для его значения.
- Settings является обязательным свойством для ресурса DSC и ожидает получения хэш-статьи для его значения.
-
LastModified является свойством ReadOnly для ресурса DSC и ожидает получения значения DateTime для его значения из
Get()
метода . - Format является необязательным свойством для ресурса DSC и ожидает получения значения String .
Значения свойств по умолчанию
При создании экземпляра ресурса DSC на основе класса используется конструктор без параметров по умолчанию. Если вы не переопределите это поведение, конструктор без параметров по умолчанию инициализирует каждое свойство значением по умолчанию для его типа. Если свойство определено с явным значением по умолчанию, вместо него используется это значение. Дополнительные сведения о конструкторах для ресурсов DSC на основе классов см. в разделе Конструкторы.
Значение по умолчанию определяет, является ли свойство ссылочным типом или типом значения .
Ссылочные типы инициализируются в $null
. Типы значений инициализируются значением, указанным в определении.
В отличие от других реализаций ресурсы DSC на основе классов управляют всеми определенными свойствами, имеющими атрибут DscProperty , даже если это свойство не указано в конфигурации DSC или при использовании Invoke-DscResource
. Так как свойства типа значения имеют значение по умолчанию, отличное от NULL, ресурс DSC на основе класса не может различать свойство, которое не было указано, и свойство, указанное в качестве значения по умолчанию.
Важно!
При использовании ресурса DSC на основе класса всем свойствам типа значения, которые не заданы явно, всегда присваиваются значения по умолчанию, как определено в ресурсе DSC.
Невозможно использовать ресурс DSC на основе классов без управления всеми свойствами типа значений, определенными для этого ресурса DSC. В отличие от других ресурсов DSC, удаление свойства из конфигурации DSC или из вызова Invoke-DscResource
не игнорирует состояние этого свойства. Он сбрасывает его до значения по умолчанию.
Для ресурса DSC на основе класса могут быть неуправляемы только свойства ссылочного типа.
Вы можете проверка, является ли тип ссылочным или типом значения, проверив его BaseType.
function Test-IsValueType ($Object) {
$base = $Object.GetType().BaseType
while ($true) {
switch ($base.FullName) {
'System.Object' { return $false }
'System.ValueType' { return $true }
default {
$base = $base.BaseType
}
}
}
}
Test-IsValueType 'foo'
Test-IsValueType 5
False
True
В этой таблице содержится несколько типов, часто используемых в ресурсах DSC. В нем указывается, являются ли они ссылочными типами или типами значений, а если они являются типами значений, то каково их значение по умолчанию при инициализации ресурса DSC.
Имя | Type | Значение по умолчанию |
---|---|---|
System.Enum | Значение | 0 |
System.Int32 | Значение | 0 |
System.Double | Значение | 0 |
System.DateTime | Значение | 1 января 0001 г. 0:00:00 |
System.TimeSpan | Значение | Для всех полей задано значение 0 . |
System.String | Ссылка | $null |
System.Management.Automation.PSCredential | Ссылка | $null |
Атрибуты свойства проверки
Свойства ресурса DSC на основе класса также могут использовать атрибуты проверки для ограничения пользовательских значений для свойства. Проверка применяется при компиляции конфигурации DSC или вызове Invoke-DSCResource
. VS Code не проверяет значения, указанные в конфигурации DSC, во время ее редактирования.
Внимание!
При использовании Invoke-DscResource
сбои проверки свойств не помешает командлету Get()
вызвать метод , Test()
или Set()
. Чтобы предотвратить вызов метода командлетом при сбое входного атрибута проверки свойства, укажите errorActionPreference как Stop
.
Определение атрибутов проверки для свойств проще, чем реализация той же логики в методе и позволяет обнаруживать метаданные о классе, который определяет ресурс DSC. Там, где это возможно, лучше явно указать значения, которые принимаются свойствами ресурса DSC. Это объясняет использование и обеспечивает более безопасный и надежный интерфейс.
Рассмотрим этот фрагмент определения ресурса DSC на MyDscResource
основе класса:
[DscResource()]
class MyDscResource {
[DscProperty()]
[string]
[ValidateSet('JSON', 'YAML')]
$Format
}
Он использует атрибут ValidateSet для ограничения допустимых значений свойства Format до JSON
и YAML
. Если для параметра Формат используется Invoke-DscResource
недопустимое значение, командлет вызывает ошибку:
$Parameters = @{
Name = 'MyDscResource'
ModuleName = 'MyDscResources'
Method = 'Get'
Property = @{
Path = '/Dsc/Example/config.yaml'
Format = 'Incorrect'
Settings = @{
Foo = 'Bar'
}
}
}
Invoke-DscResource @Parameters -ErrorAction Stop
Invoke-DscClassBasedResource: Exception setting "Format": "The argument
"Incorrect" does not belong to the set "YAML,JSON" specified by the
ValidateSet attribute. Supply an argument that is in the set and then
try the command again."
Дополнительные сведения об атрибутах проверки см. в разделе about_Functions_Advanced_Parameters.
Свойства перечисления
Для лучшей разработки и взаимодействия с пользователем по сравнению с использованием атрибута ValidateSet можно определить перечисление , задающее набор допустимых значений.
Например, можно определить перечисление FormatOption и использовать его в качестве типа для свойства Format ресурса DSC на основе класса:
enum FormatOption {
JSON
YAML
}
[DscResource()]
class MyDscResource {
[DscProperty()]
[FormatOption]
$Format
}
Сообщение об ошибке для недопустимого значения перечисления короче и понятнее, чем для ValidateSet:
$Parameters = @{
Name = 'MyDscResource'
ModuleName = 'MyDscResources'
Method = 'Get'
Property = @{
Path = '/Dsc/Example/config.yaml'
Format = 'Incorrect'
Settings = @{}
}
}
Invoke-DscResource @Parameters -ErrorAction Stop
Invoke-DscClassBasedResource: Exception setting "Format": "Cannot
convert value "Incorrect" to type "FormatOption". Error: "Unable to
match the identifier name Incorrect to a valid enumerator name. Specify
one of the following enumerator names and try again: JSON, YAML""
Перечисления также полезны, если необходимо использовать одно и то же свойство в нескольких ресурсах DSC на основе классов. Вы можете определить перечисление один раз и использовать его везде, где вам нужно, тогда как с помощью атрибута ValidateSet необходимо обновить каждый ресурс DSC, который использует свойство .
Дополнительные сведения о перечислениях в PowerShell см. в разделе about_Enum.
Свойство Ensure
Многие ресурсы DSC имеют свойство Ensure , которое управляет состоянием экземпляра ресурса DSC. Например, User
ресурс DSC в модуле PSDscResources имеет свойство Ensure , которое принимает значения Present
(указывает, что пользователь должен существовать) и Absent
(указывает, что пользователь не должен существовать).
Для ресурсов DSC на основе классов рекомендуется создать перечисление Ensure и использовать его для любых ресурсов DSC в качестве типа для свойства с именем Ensure
. Пример:
enum Ensure {
Absent
Present
}
[DscResource()]
class MyDscResource {
[DscProperty()]
[Ensure]
$Ensure
}
Хотя перечисление Ensure обычно определяет значения Absent
и Present
, оно может определить любые значения, имеющие смысл для ресурса DSC.
Используя в качестве примера ресурс DSC из этой статьи SimpleConfig
, вместо того чтобы иметь Absent
только (файл конфигурации не должен существовать) и Present
, можно определить , чтобы иметь следующие значения:
-
Absent
— Конфигурация не должна существовать по указанному пути. Если это так, ресурс DSC должен удалить его из системы. -
Exactly
— Конфигурация должна существовать по указанному пути только с параметрами, определенными в свойстве Параметры . Если какие-либо параметры имеют неправильное значение, ресурс DSC должен исправить их. Если в файле конфигурации есть параметры, не указанные в свойстве Параметры, они должны быть удалены . -
Include
— Конфигурация должна существовать по указанному пути с параметрами, определенными в свойстве Параметры . Если какие-либо параметры имеют неправильное значение, ресурс DSC должен исправить их. Если в файле конфигурации есть параметры, не указанные в свойстве Параметры , они должны игнорироваться. -
Present
— конфигурация должна существовать по указанному пути. Если это не так, ресурс DSC должен создать его с параметрами, определенными в свойстве Параметры . Если это так, ресурс DSC должен сообщить, что экземпляр находится в нужном состоянии, даже если параметры не соответствуют параметрам, указанным в свойстве Параметры .
Это перечисление можно определить следующим образом:
enum Ensure {
Absent
Exactly
Include
Present
}
Сложные свойства
Некоторые свойства ресурса DSC могут иметь вложенные свойства. Например, свойство Settings ресурса DSC этой статьи SimpleConfig
было указано ранее в этой статье с типом Hashtable . Это позволяет пользователю указывать любые имена ключей и типы значений для каждого ключа.
Вместо этого для управления допустимыми параметрами можно написать класс, представляющий сложное свойство. Чтобы свойства этого класса были распознаны DSC как подсвойства, они должны иметь атрибут DscProperty .
class SimpleConfigSettings {
[DscProperty()] [string]
$ProfileName
[DscProperty()] [string]
$Description
[DscProperty()] [int]
[ValidateRange(0,90)]
$CheckForUpdates
}
Класс SimpleConfigSettings определяет три параметра: ProfileName в качестве строки, Description в виде строки и CheckForUpdates как int , значение которого должно быть в диапазоне от 0 до 90.
Примечание
Несмотря на то, что сложные свойства определяются как классы и их подсвойства должны иметь атрибут DscProperty , атрибут свойства ресурса DSC является единственным, который применяет любые изменения поведения к свойствам. Пометка вложенных свойств как Key, Mandatory или NotConfigurable не влияет на поведение DSC при компиляции конфигурации DSC или использовании Invoke-DscResource
.
Определив класс , его можно использовать в качестве свойства ресурса DSC:
[DscResource()]
class SimpleConfig {
[DscProperty(Mandatory)] [SimpleConfigSettings]
$Settings
}
Если параметры определены как тип SimpleConfigSettings , пользователи получают четкие сведения о значении, которое им нужно предоставить.
$Parameters = @{
Name = 'MyDscResource'
ModuleName = 'MyDscResources'
Method = 'Get'
Property = @{
Path = '/Dsc/Example/config.yaml'
Format = 'YAML'
Settings = @{ Name = 'Foo' }
}
}
Invoke-DscResource @Parameters -ErrorAction Stop
Invoke-DscClassBasedResource: Exception setting "Settings": "Cannot
create object of type "SimpleConfigSettings". The Name property was not
found for the SimpleConfigSettings object. The available property is:
[ProfileName <System.String>] , [Description <System.String>] ,
[CheckForUpdates <System.Int32>]"
Сложные свойства могут иметь свойства, которые также являются сложными свойствами. Уровень вложенности, который можно использовать, не ограничен. Для оптимального взаимодействия с пользователем ограничьте глубину сложных свойств тремя уровнями.
class SimpleConfigUpdateSettings {
[DscProperty()] [int]
[ValidateRange(0,90)]
$Interval
[DscProperty()] [string]
$Url
}
class SimpleConfigSettings {
[DscProperty()] [string]
$ProfileName
[DscProperty()] [string]
$Description
[DscProperty()] [SimpleConfigUpdateSettings]
$Updates
}
[DscResource()]
class SimpleConfig {
[DscProperty(Mandatory)] [SimpleConfigSettings]
$Settings
}
В этом примере показано, как определение вложенных сложных свойств обеспечивает проверку. Эта проверка предоставляет полезные сообщения об ошибках при вызове Invoke-DscResource
.
$Parameters = @{
Name = 'MyDscResource'
ModuleName = 'MyDscResources'
Method = 'Get'
Property = @{
Path = '/Dsc/Example/config.yaml'
Format = 'YAML'
Settings = @{
ProfileName = 'Foo'
Updates = @{
Interval = 30
Oops = 'Invalid property'
}
}
}
}
Invoke-DscResource @Parameters -ErrorAction Stop
Invoke-DscClassBasedResource: Exception setting "Settings": "Cannot
create object of type "SimpleConfigSettings". Cannot create object of
type "SimpleConfigUpdateSettings". The Interval property was not found
for the SimpleConfigUpdateSettings object. The available property is:
[UpdateInterval <System.Int32>] , [UpdateUrl <System.String>]"
Свойство Reasons
Если ресурс DSC на основе класса предназначен для использования с функцией конфигурации компьютера автоматического управления Azure, ресурс DSC должен иметь свойство Reasons , соответствующее следующим требованиям:
- Он должен быть объявлен со свойством NotConfigurable в атрибуте DscProperty .
- Это должен быть массив объектов, имеющих свойство Stringс именем Code, свойство String с именем Phrase и никакие другие свойства. Тип объекта можно определить как хэш-строку или создать объект как сложное свойство.
Конфигурация компьютера использует свойство Reasons для стандартизации представления сведений о соответствии. Каждый объект, возвращаемый методом Get()
для свойства Reasons, определяет, как и почему экземпляр ресурса DSC не соответствует требованиям.
Конфигурация компьютера ожидает свойства Code и Phrase . Свойство Phrase должно быть доступной для чтения строкой, объясняющей, как экземпляр выходит из нужного состояния. Свойство Code должно быть отформатировано специально, чтобы конфигурация компьютера четко отображала сведения об аудите для ресурса DSC.
Свойство Code использует это форматирование без пробелов:
<ResourceName>:<ResourceName>:<Identifier>
В этом форматировании замените <ResourceName>
фактическим именем ресурса DSC и <Identifier>
коротким именем, из-за чего ресурс DSC выходит за пределы состояния. Свойство Code не должно содержать пробелы. Например, если ресурс DSC с именем Tailspin не соответствует требованиям, так как файл конфигурации не существует, код может иметь значение Tailspin:Tailspin:ConfigFileNotFound
.
В этом фрагменте кода показано, как определить свойство Reasons в виде хэш-таблице:
class MyDscResource {
[DscProperty(NotConfigurable)]
[hashtable[]] $Reasons
}
Чтобы определить свойство Reasons как сложное свойство, необходимо определить для него класс, а затем добавить его в ресурс DSC:
class MyModuleReason {
[DscProperty()]
[string] $Code
[DscProperty()]
[string] $Phrase
}
class MyDscResource {
[DscProperty(NotConfigurable)]
[MyModuleReason[]] $Reasons
}
Примечание
Класс, определенный для свойства Reasons , называется MyModuleReason
вместо Reason
, используя имя модуля в качестве префикса. Хотя можно присвоить классу любое имя, если два или более модулей определяют класс с одинаковым именем и оба используются в конфигурации, PowerShell вызывает исключение.
Чтобы избежать исключений, вызванных конфликтами имен в DSC и конфигурации компьютера, всегда введите префикс имени класса, определяемого для свойства Reasons .
Свойства, не относящиеся к ресурсам
При определении ресурса DSC на основе класса можно добавить свойства, у которых нет атрибута DscProperty . Эти свойства нельзя использовать непосредственно с Invoke-DscResource
конфигурацией DSC или в ней. Они могут использоваться внутри класса или непосредственно пользователем, создав экземпляр класса самостоятельно.
Дополнительные сведения о свойствах класса см. в разделе about_Classes.
Методы ресурсов DSC на основе классов
Ресурсы DSC на основе классов должны реализовывать три метода:
-
Get()
для получения текущего состояния ресурса DSC -
Test()
, чтобы проверить, находится ли ресурс DSC в требуемом состоянии -
Set()
для принудительного применения требуемого состояния ресурса DSC
Сигнатура метода определяется ожидаемым типом выходных данных и параметрами. Класс не будет признан допустимым ресурсом DSC, если он не содержит правильных сигнатур для этих методов.
Методы класса PowerShell отличаются от функций несколькими важными способами. Для написания ресурса DSC на основе класса наиболее важны следующие:
- В методах класса никакие объекты не отправляются в конвейер, за исключением объектов, упомянутых в инструкции
return
. Случайные выходные данные конвейера из кода отсутствуют. Если метод имеет тип вывода, отличный от Void, необходимо указать инструкциюreturn
для выдачи объекта этого типа. - Неустранимые ошибки, записанные в поток ошибок из метода класса, не передаются. Необходимо использовать для
throw
отображения неустранимой ошибки. - Чтобы получить доступ к значению свойства экземпляра класса, используйте
$this.<PropertyName>
. Не устанавливайте и не обновляйте свойства класса с атрибутом DscProperty . Они задаются, когда пользователь указывает параметр Property сInvoke-DscResource
или при определении блока ресурсов DSC в конфигурации DSC.
Дополнительные сведения о методах класса см. в разделе about_Classes.
Методы могут вызывать командлеты и собственные команды, включая команды, определенные в том же модуле, что и ресурс DSC на основе класса.
Get
Метод Get()
используется для получения текущего состояния ресурса DSC и возврата его в виде объекта . Он должен определять свои выходные данные как сам класс и не принимать параметров.
Например, ресурс MyDscResource
DSC на основе класса должен иметь такую сигнатуру:
[MyDscResource] Get() {
# Implementation here
}
Get()
Чтобы метод возвращал правильный объект, необходимо создать экземпляр класса .
Затем можно заполнить свойства этого экземпляра текущими значениями из системы. Наконец, используйте return
ключевое слово для вывода текущего состояния.
[MyDscResource] Get() {
$CurrentState = [MyDscResource]::new()
if (Test-Path -Path $this.Path) {
$CurrentState.Ensure = [Ensure]::Present
$CurrentState.Path = $this.Path
} else {
$CurrentState.Ensure = [Ensure]::Absent
}
return $CurrentState
}
В примере реализации метод инициализирует Get()
$CurrentState
переменную с помощью конструктора по умолчанию для MyDscResource
класса . Он проверяет, существует ли файл, указанный в свойстве Path . Если это так, метод присваивает свойствам Ensure и Path значение $CurrentState
Present
и соответствующий путь. Если это не так, метод задает для параметра Ensure значение Absent
. Наконец, метод использует return
оператор для отправки текущего состояния в качестве выходных данных.
Тест
Метод Test()
используется для проверки того, находится ли ресурс DSC в нужном состоянии, и возвращает $true
значение , если он находится в нужном состоянии или $false
нет. Он должен определять логические выходные данные и не принимать параметров.
Сигнатура Test()
метода всегда должна соответствовать следующему:
[bool] Test() {
# Implementation here
}
Вместо повторного выполнения логики из Get()
метода вызовите Get()
метод и назначьте его выходные данные переменной.
[bool] Test() {
$InDesiredState = $true
$CurrentState = $this.Get()
if ($CurrentState.Ensure -ne $this.Ensure) {
$InDesiredState = $false
}
# Check remaining properties as needed.
return $InDesiredState
}
В примере реализации метод инициализирует Test()
переменную , как $true
и раньше, $InDesiredState
задавая $CurrentState
выходные данные Get()
метода для ресурса DSC на основе класса.
Затем он проверяет значения свойств класса , указанные $CurrentState
в экземпляре ресурса DSC, присвоив значение $InDesiredState
, $false
если какие-либо свойства не в нужном состоянии.
Наконец, он выводит, находится ли экземпляр ресурса DSC в нужном состоянии с помощью инструкции return
.
Set
Метод Set()
используется для принудительного применения требуемого состояния ресурса DSC. Он не имеет выходных данных и не принимает параметров.
Сигнатура Set()
метода всегда должна соответствовать следующему:
[void] Set() {
# Implementation here
}
Set()
Реализация метода не может использовать никакие return
инструкции. Он должен быть записан для идемпотентного применения требуемого состояния.
Примечание
Если необходимо применить требуемое состояние в зависимости от текущего состояния системы, может потребоваться получить текущее состояние с Get()
помощью метода .
Например, у вас может быть логика для создания службы, если она не существует, вместо исправления неправильного значения свойства.
Именно поэтому это важно при вызове Invoke-DscResource
Test()
метода и вызове Set()
метода только в том случае, если Test()
возвращает .$false
Хотя все ресурсы DSC должны быть идемпотентными, у вас нет гарантии, что любой ресурс DSC действительно идемпотентен, не проверяя его реализацию.
Необязательные методы
Помимо обязательных Get()
методов , Test()
и Set()
ресурс DSC на основе класса может определить любое количество дополнительных методов. Одним из вариантов использования для этого является определение вспомогательных методов, например для кода, используемого в нескольких обязательных методах.
Это также полезно при определении класса, представляющего программный компонент для не только конфигурации. Например, можно определить класс, который одновременно является ресурсом DSC, обеспечивающим идемпотентную конфигурацию приложения и вызывающим само приложение для выполнения задач. Это позволит определить класс один раз и использовать его как с DSC, так и с функциями, экспортируемыми из модуля для использования приложения.
Конструкторы
Конструктор — это метод, который создает новый экземпляр класса . Имя метода всегда совпадает с именем класса и не определяет тип вывода.
Не обязательно определять конструкторы для ресурса DSC на основе класса. Если конструктор не определен, используется конструктор без параметров по умолчанию. Этот конструктор инициализирует все члены значениями по умолчанию. Типы объектов и строки получают значения NULL.
При определении конструктора конструктор без параметров по умолчанию не создается. Ресурс DSC на основе класса должен иметь конструктор без параметров, поэтому если вы определяете какие-либо настраиваемые конструкторы, по крайней мере один из них должен быть определен без каких-либо параметров.
При использовании Invoke-DscResource
или компиляции конфигурации DSC ресурс DSC создается с помощью конструктора без параметров, а затем каждое указанное свойство задается в экземпляре .
Примечание
При определении конструктора исключение должно вызываться только в том случае, если ресурс DSC по какой-либо причине недействителен в системе. Например, ресурс DSC на основе класса, который работает только в Windows, может вызвать исключение, если он создан в системе, отличной от Windows.
Дополнительные сведения о конструкторах см . в разделе about_Classes
Определение конструктора по умолчанию
Ресурсы DSC на основе классов требуют, чтобы класс не реализовал конструкторы или один с этой сигнатурой:
<DscResourceClassName>() {
# Implementation here
}
Если для выполнения не требуется логика, например установка значений по умолчанию на основе операционной системы, вам не нужно писать код в конструкторе. В следующем примере показано минимальное определение для конструктора по умолчанию:
MyDscResource() {}
Вы можете добавить код в конструктор, чтобы задать значения по умолчанию для свойств класса . Например, может потребоваться задать значение на основе целевой операционной системы:
MyDscResource() {
if ($IsWindows) {
$this.Format = 'JSON'
} else {
$this.Format = 'YAML'
}
}
Примечание
Помните, что проверка свойств в DSC происходит после использования конструктора, а не во время. Не пытайтесь проверить свойства в конструкторе.
Определение пользовательского конструктора
DSC вызывает только конструктор без параметров. Однако можно определить другие конструкторы с параметрами, если класс используется в других обстоятельствах, например в функциях в модуле.
Дополнительные сведения об определении конструкторов см. в разделе about_Classes
Рекомендации
Это не исчерпывающий список рекомендаций по созданию высококачественных ресурсов DSC на основе класса, которые являются идемпотентными, безопасными и обслуживаемыми. Он дополняет контрольный список разработки ресурсов DSC, который определяет более общие рекомендации по созданию ресурсов DSC. Рекомендации в этом разделе относятся к ресурсам DSC на основе классов.
Использование атрибутов проверки
Если вы можете проверить свойство с одним или несколькими атрибутами проверки, сделайте это. Эта проверка проверяется перед вызовом любого метода с Invoke-DscResource
и при компиляции конфигурации DSC. Более раннее возникновение ошибки снижает вероятность того, что ресурс DSC непредсказуемо завершится сбоем при применении состояния.
Ошибки, вызванные встроенными атрибутами проверки, также четко определяют, какое свойство имеет недопустимое значение и как это значение было недопустимым.
Примечание
Используйте атрибуты проверки только для того, чтобы убедиться, что введенные пользователем данные для свойства являются допустимыми, а не для того, чтобы проверить, находится ли свойство в правильном состоянии. Вот для чего Test()
предназначен метод.
Например, не проверяйте, существует ли значение Path , если оно не требуется для работы остальной логики ресурса DSC. Если ресурс DSC создает файл в этом расположении, не проверяйте его существование в объявлении свойства.
Если вы используете какие-либо сложные свойства, обязательно примените атрибуты проверки и к этим вложенным свойствам. Эти вложенные свойства проверяются одновременно с родительским свойством.
Использование перечислений вместо ValidateSet
Если свойство ресурса DSC на основе класса имеет список допустимых значений, которые оно принимает, определите его как свойство перечисления вместо использования атрибута ValidateSet .
Это позволяет пользователям лучше отображать сообщения об ошибках и упрощает обслуживание, если вы используете эти значения в любом другом месте модуля. Вместо обновления каждого командлета или проверка для этого свойства можно обновить определение перечисления.
Помните, что перечисления являются свойствами типа значений. По умолчанию используется 0
значение при создании экземпляра ресурса DSC на основе класса. Если задать явное значение по умолчанию для свойства перечисления, это перечисление не может быть неуправляемым. Если пользователь не указывает свойство , ресурс DSC ведет себя так же, как если бы пользователь явно указал значение по умолчанию.
Чтобы поддерживать неуправляемые свойства перечисления, не определяйте метку для 0
значения. По умолчанию, если не указать целочисленное значение для каких-либо меток при использовании инструкции enum
, первая объявленная метка имеет значение 0
. Вместо этого определите первую метку со значением 1
(или любым более высоким значением).
Пример:
enum OptionalSetting {
FirstOption = 1
SecondOption
ThirdOption
}
Затем в Test()
методах и Set()
можно игнорировать свойство перечисления, если значение равно 0
.
Если Test()
свойство перечисления имеет значение 0
, игнорируйте текущее состояние ресурса DSC в системе. Не сообщайте ресурс DSC как о выходе из требуемого состояния, если текущее состояние является допустимым значением.
В Set()
убедитесь, что логика изменения состояния системы игнорирует свойство перечисления, если оно является 0
.
Примечание
Этот метод для реализации свойств перечисления, которые могут быть неуправляемы, работает только в том случае, если базовое значение меток перечисления не имеет значения или если 0
не является допустимым базовым значением.
Явное определение значений по умолчанию для свойств типа значения
При создании ресурса DSC на основе класса убедитесь, что свойства задают правильные значения по умолчанию для каждого свойства типа значения. Необходимо обеспечить синхронизацию значений по умолчанию с значениями компонента, которым управляет ресурс DSC.
Задокументируйте поведение этих свойств для пользователей. Убедитесь, что в документации указано, что для этих свойств заданы значения по умолчанию, если пользователь не указывает их при использовании ресурса DSC.
Убедитесь, что ресурс DSC учитывает свойства неуправляемого ссылочного типа
Поскольку свойства ссылочного типа инициализируются в $null
, в отличие от свойств типа значения, ресурс DSC может различать, было ли указано свойство ссылочного типа. Убедитесь, что ресурсы DSC игнорируют неуправляемые свойства ссылочного типа в методах Test()
и Set()
.
Если Test()
свойство ссылочного типа имеет значение $null
, игнорируйте текущее состояние ресурса DSC в системе. Не сообщайте ресурс DSC как о выходе из требуемого состояния, если текущее состояние не $null
равно .
В Set()
убедитесь, что логика изменения состояния системы игнорирует все свойства ссылочного типа, которые являются $null
.
Использование настраиваемого атрибута проверки вместо ValidateScript
Для свойств, требующих более сложной проверки, рассмотрите возможность определения собственного атрибута, наследуемого от класса ValidateArgumentsAttribute или одного из его производных.
Это обеспечивает гораздо больше контроля над проверкой свойства и обменом сообщениями в случае сбоя проверки указанного значения.
Например, это определение атрибута ValidateHttpsUrl гарантирует, что указанное значение является допустимым URL-адресом HTTPS.
using namespace System.Management.Automation
class ValidateHttps : ValidateArgumentsAttribute {
[void] Validate([object]$Url, [EngineIntrinsics]$engineIntrinsics) {
[uri]$Uri = $Url
if($Uri.Scheme -ne 'https') {
$Message = @(
"Specified value '$Url' is not a valid HTTPS URL."
"Specify an absolute URL that begins with 'https://'."
) -join ' '
throw [System.ArgumentException]::new($Message)
}
}
}
При применении к свойству ресурс DSC создает полезное сообщение об ошибке:
$Parameters = @{
Name = 'MyDscResource'
ModuleName = 'MyDscResources'
Method = 'Get'
Property = @{
Url = 'http://contoso.com/updater'
}
}
Invoke-DscResource @Parameters -ErrorAction Stop
Invoke-DscClassBasedResource: Exception setting "Url": "Specified value
'http://contoso.com/updater' is not a valid HTTPS URL. Specify an absolute
URL that begins with 'https://'."
Примечание
Из-за ограничений В DSC нельзя определить и использовать настраиваемый атрибут проверки в том же модуле, что и ресурс DSC на основе класса. Вместо этого необходимо определить настраиваемый атрибут проверки в отдельном .psm1
файле, добавить его в манифест модуля main в параметре NestedModules и указать инструкцию using
в файле, в котором определен ресурс DSC на основе класса.
Например, если вы определили атрибут ValidateHttps в Validators.psm1
, вам потребуется иметь его в манифесте модуля:
{
NestedModules = @(
'Validators.psm1'
)
}
В верхней части файла модуля вы определяете ресурс DSC на основе класса:
using module ./Validators.psm1
В этом примере Validators.psm1
находится в той же папке, что и модуль, где определен ресурс DSC на основе класса. Если файлы находятся в разных папках, необходимо указать относительный путь к модулю, который определяет атрибут проверки.
Использование сложных свойств вместо хэш-данных
Если ресурс DSC имеет свойство с известными подсвойствами, создайте для него класс и определите эти вложенные свойства в этом классе. Это обеспечивает более удобную для обнаружения область для параметров и позволяет применять проверку для вложенных свойств. Дополнительные сведения см. в статье о сложных свойствах.
Добавление метода Проверки, если свойства являются взаимозависимыми
У вас может быть ресурс DSC со свойствами, которые необходимо объединить для проверки. Эти свойства не могут быть проверены атрибутом проверки. Добавьте метод проверки в ресурс DSC на основе класса и вызовите его в начале Get()
методов , Test()
и Set()
.
Например, если ресурс DSC для управления файлом конфигурации имеет свойства Path и Extension , может потребоваться проверить:
- Расширение файла, указанное в качестве пути , совпадает со значением Расширения или Расширение не указано.
- Это расширение указывается, если значение path является папкой, а не файлом.
Метод проверки должен иметь однозначное имя, не возвращать выходные данные и вызывать исключение в случае сбоя проверки экземпляра.
[void] ValidatePath() {
$ExtensionSpecified = ![string]::IsNullOrEmpty($this.Extension)
$PathExtension = Split-Path -Path $this.Path -Extension
if (
$PathExtension -and
$ExtensionSpecified -and
($PathExtension -ne $this.Extension)
) {
$Message = @(
"Specified Path '$($this.Path)' has an extension ('$PathExtension')"
"which doesn't match the value of the Extension property"
"'$($this.Extension)'. When specifying the Extension property with"
"the Path property as a specific file, the extension of Path's"
"value must be the same as the value of Extension or Extension must"
"not be specified."
) -join ' '
throw [System.ArgumentException]::new($Message)
} elseif (!$ExtensionSpecified) {
$Message = @(
"Specified Path '$($this.Path)' has no extension and the Extension"
"property wasn't specified. When the value of Path is a folder, the"
"Extension property is mandatory. Specify a value for Extension."
) -join ' '
throw [System.ArgumentException]::new($Message)
}
}
Если вам нужно проверить несколько различных параметров или групп параметров таким образом, определите универсальный метод проверки, который вызывает другие параметры. Используйте этот метод в Get()
, Test()
и Set()
.
Извлечение общего кода в методы или функции
Если ваши методы являются длинными со сложной логикой или повторно используют один и тот же код между ними, создайте вспомогательный метод или функцию и переместите код туда. Это упрощает тестирование и обслуживание ресурса DSC. Это также упрощает чтение и понимание методов ресурса DSC.