تأليف مورد DSC المستند إلى الفئة
يمكنك تعريف مورد DSC عن طريق إنشاء فئة PowerShell. في مورد DSC المستند إلى الفئة، يتم تعريف المخطط كخصائص للفئة التي يمكن تعديلها باستخدام السمات لتحديد نوع الخاصية. يتم تنفيذ المورد باستخدام أساليب Get و Set و Test (مساوية Get-TargetResource
Set-TargetResource
للدالات و و Test-TargetResource
في مورد البرنامج النصي).
في هذه المقالة، نقوم بإنشاء الحد الأدنى من الموارد المسماة NewFile
التي تدير ملفا في مسار محدد.
لمزيد من المعلومات حول موارد DSC، راجع موارد DSC.
ملاحظة
المجموعات العامة غير مدعومة في الموارد المستندة إلى الفئة.
بنية المجلد لمورد فئة
لتنفيذ مورد DSC مع فئة PowerShell، قم بإنشاء بنية المجلد التالية. يتم تعريف الفئة في MyDscResource.psm1
ويتم تعريف بيان الوحدة النمطية في MyDscResource.psd1
.
$env:ProgramFiles\WindowsPowerShell\Modules (folder)
|- MyDscResource (folder)
MyDscResource.psm1
MyDscResource.psd1
إنشاء الفئة
يمكنك استخدام class
الكلمة الأساسية لإنشاء فئة PowerShell. لتحديد أن الفئة هي مورد DSC، استخدم السمة DscResource()
. اسم الفئة هو اسم مورد DSC.
[DscResource()]
class NewFile {
}
تعريف الخصائص
يتم تعريف مخطط مورد DSC على أنه خصائص للفئة . نعلن عن ثلاث خصائص على النحو التالي.
[DscProperty(Key)]
[string] $path
[DscProperty(Mandatory)]
[ensure] $ensure
[DscProperty()]
[string] $content
[DscProperty(NotConfigurable)]
[MyDscResourceReason[]] $Reasons
لاحظ أن الخصائص يتم تعديلها بواسطة السمات. معنى السمات كما يلي:
- DscProperty(Key): الخاصية مطلوبة. الخاصية هي مفتاح. يجب دمج قيم جميع الخصائص التي تم وضع علامة عليها كمفاتيح لتعريف مثيل مورد بشكل فريد داخل تكوين.
- DscProperty(إلزامي): الخاصية مطلوبة.
- DscProperty(NotConfigurable): الخاصية للقراءة فقط. لا يمكن تعيين الخصائص التي تم وضع علامة عليها بهذه السمة بواسطة تكوين، ولكن يتم ملؤها بواسطة أسلوب Get .
- DscProperty(): الخاصية قابلة للتكوين، ولكنها غير مطلوبة.
الخاصيتان PathوS sourcePath هما كلتا السلاسل. وقت الإنشاء هو خاصية DateTime. الخاصية Ensure هي نوع تعداد، معرف على النحو التالي.
enum Ensure {
Absent
Present
}
تضمين الفئات
إذا كنت ترغب في تضمين نوع جديد مع خصائص محددة يمكنك استخدامها داخل مورد DSC الخاص بك، فقم بإنشاء فئة مع أنواع الخصائص كما هو موضح من قبل.
class MyDscResourceReason {
[DscProperty()]
[string] $Code
[DscProperty()]
[string] $Phrase
}
ملاحظة
MyDscResourceReason
يتم الإعلان عن الفئة هنا باسم الوحدة النمطية كبادئة. بينما يمكنك إعطاء الفئات المضمنة أي اسم، إذا حددت وحدتان أو أكثر فئة بنفس الاسم ويتم استخدام كليهما في تكوين، فإن PowerShell يثير استثناء.
لتجنب الاستثناءات الناجمة عن تعارضات الأسماء في DSC، قم ببادئة أسماء الفئات المضمنة باسم الوحدة النمطية. إذا كان من غير المحتمل أن يتعارض اسم الفئة المضمنة بالفعل، يمكنك استخدامه دون بادئة.
إذا تم تصميم مورد DSC للاستخدام مع ميزة تكوين جهاز Azure Automanage، فقم دائما ببادئة اسم الفئة المضمنة التي تقوم بإنشائها للخاصية Reasons .
الوظائف العامة والخاصة
يمكنك إنشاء وظائف PowerShell داخل نفس ملف الوحدة النمطية واستخدامها داخل أساليب فئة مورد DSC الخاص بك. يجب تصدير الدالات كأعضاء وحدة نمطية في إعداد FunctionsToExport الخاص ببيان الوحدة النمطية. قد تستدعي كتل البرنامج النصي داخل هذه الدالات دالات غير منفذة.
<#
Public Functions
#>
function Get-File {
param(
[ensure]$ensure,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
$fileContent = [MyDscResourceReason]::new()
$fileContent.code = 'file:file:content'
$filePresent = [MyDscResourceReason]::new()
$filePresent.code = 'file:file:path'
$ensureReturn = 'Absent'
$fileExists = Test-Path -Path $path -ErrorAction SilentlyContinue
if ($fileExists) {
$filePresent.phrase = @(
"The file was expected to be: $ensure"
"The file exists at path: $path"
) -join "`n"
$existingFileContent = Get-Content $path -Raw
if ([string]::IsNullOrEmpty($existingFileContent)) {
$existingFileContent = ''
}
if (![string]::IsNullOrEmpty($content)) {
$content = $content | ConvertTo-SpecialChars
}
$fileContent.phrase = @(
"The file was expected to contain: $content"
"The file contained: $existingFileContent"
) -join "`n"
if ($content -eq $existingFileContent) {
$ensureReturn = 'Present'
}
} else {
$filePresent.phrase = @(
"The file was expected to be: $ensure"
"The file does not exist at path: $path"
) -join "`n"
$path = 'file not found'
}
@{
Ensure = $ensureReturn
Path = $path
Content = $existingFileContent
Reasons = @($filePresent,$fileContent)
}
}
function Set-File {
param(
[ensure]$ensure = "Present",
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
Remove-Item $path -Force -ErrorAction SilentlyContinue
if ($ensure -eq "Present") {
New-Item $path -ItemType File -Force
if ([ValidateNotNullOrEmpty()]$content) {
$content | ConvertTo-SpecialChars | Set-Content $path -NoNewline -Force
}
}
}
function Test-File {
param(
[ensure]$ensure = "Present",
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
$test = $false
$get = Get-File @PSBoundParameters
if ($get.ensure -eq $ensure) {
$test = $true
}
$test
}
<#
Private Functions
#>
function ConvertTo-SpecialChars {
param(
[parameter(Mandatory = $true,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string]$string
)
$specialChars = @{
'`n' = "`n"
'\\n' = "`n"
'`r' = "`r"
'\\r' = "`r"
'`t' = "`t"
'\\t' = "`t"
}
foreach ($char in $specialChars.Keys) {
$string = $string -replace ($char,$specialChars[$char])
}
$string
}
تنفيذ الأساليب
أساليب Get و Set و Test مشابهة Get-TargetResource
Set-TargetResource
للدالات و و Test-TargetResource
في مورد البرنامج النصي.
من أفضل الممارسات الحد من مقدار التعليمات البرمجية داخل تنفيذ الفئة. انقل غالبية التعليمات البرمجية الخاصة بك إلى وظائف الوحدة النمطية المصدرة، والتي يمكنك اختبارها بشكل غير مترابط.
<#
This method is equivalent of the Get-TargetResource script function.
The implementation should use the keys to find appropriate
Resources. This method returns an instance of this class with the
updated key properties.
#>
[NewFile] Get() {
$get = Get-File -ensure $this.ensure -path $this.path -content $this.content
return $get
}
<#
This method is equivalent of the Set-TargetResource script function.
It sets the Resource to the desired state.
#>
[void] Set() {
$set = Set-File -ensure $this.ensure -path $this.path -content $this.content
}
<#
This method is equivalent of the Test-TargetResource script
function. It should return True or False, showing whether the
Resource is in a desired state.
#>
[bool] Test() {
$test = Test-File -ensure $this.ensure -path $this.path -content $this.content
return $test
}
الملف الكامل
يتبع ملف الفئة الكامل.
enum ensure {
Absent
Present
}
<#
This class is used within the DSC Resource to standardize how data
is returned about the compliance details of the machine. Note that
the class name is prefixed with the module name - this helps prevent
errors raised when multiple modules with DSC Resources define the
Reasons property for reporting when they're out-of-state.
#>
class MyDscResourceReason {
[DscProperty()]
[string] $Code
[DscProperty()]
[string] $Phrase
}
<#
Public Functions
#>
function Get-File {
param(
[ensure]$ensure,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
$fileContent = [MyDscResourceReason]::new()
$fileContent.code = 'file:file:content'
$filePresent = [MyDscResourceReason]::new()
$filePresent.code = 'file:file:path'
$ensureReturn = 'Absent'
$fileExists = Test-Path -Path $path -ErrorAction SilentlyContinue
if ($fileExists) {
$filePresent.phrase = @(
"The file was expected to be: $ensure"
"The file exists at path: $path"
) -join "`n"
$existingFileContent = Get-Content $path -Raw
if ([string]::IsNullOrEmpty($existingFileContent)) {
$existingFileContent = ''
}
if (![string]::IsNullOrEmpty($content)) {
$content = $content | ConvertTo-SpecialChars
}
$fileContent.phrase = @(
"The file was expected to contain: $content"
"The file contained: $existingFileContent"
) -join "`n"
if ($content -eq $existingFileContent) {
$ensureReturn = 'Present'
}
} else {
$filePresent.phrase = @(
"The file was expected to be: $ensure"
"The file does not exist at path: $path"
) -join "`n"
$path = 'file not found'
}
@{
ensure = $ensureReturn
path = $path
content = $existingFileContent
Reasons = @($filePresent,$fileContent)
}
}
function Set-File {
param(
[ensure]$ensure = "Present",
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
Remove-Item $path -Force -ErrorAction SilentlyContinue
if ($ensure -eq "Present") {
New-Item $path -ItemType File -Force
if ([ValidateNotNullOrEmpty()]$content) {
$content | ConvertTo-SpecialChars | Set-Content $path -NoNewline -Force
}
}
}
function Test-File {
param(
[ensure]$ensure = "Present",
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$path,
[String]$content
)
$test = $false
$get = Get-File @PSBoundParameters
if ($get.ensure -eq $ensure) {
$test = $true
}
return $test
}
<#
Private Functions
#>
function ConvertTo-SpecialChars {
param(
[parameter(Mandatory = $true,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string]$string
)
$specialChars = @{
'`n' = "`n"
'\\n' = "`n"
'`r' = "`r"
'\\r' = "`r"
'`t' = "`t"
'\\t' = "`t"
}
foreach ($char in $specialChars.Keys) {
$string = $string -replace ($char,$specialChars[$char])
}
return $string
}
<#
This Resource manages the file in a specific path.
[DscResource()] indicates the class is a DSC Resource
#>
[DscResource()]
class NewFile {
<#
This property is the fully qualified path to the file that is
expected to be present or absent.
The [DscProperty(Key)] attribute indicates the property is a
key and its value uniquely identifies a Resource instance.
Defining this attribute also means the property is required
and DSC will ensure a value is set before calling the Resource.
A DSC Resource must define at least one key property.
#>
[DscProperty(Key)]
[string] $path
<#
This property indicates if the settings should be present or absent
on the system. For present, the Resource ensures the file pointed
to by $Path exists. For absent, it ensures the file point to by
$Path does not exist.
The [DscProperty(Mandatory)] attribute indicates the property is
required and DSC will guarantee it is set.
If Mandatory is not specified or if it is defined as
Mandatory=$false, the value is not guaranteed to be set when DSC
calls the Resource. This is appropriate for optional properties.
#>
[DscProperty(Mandatory)]
[ensure] $ensure
<#
This property is optional. When provided, the content of the file
will be overwridden by this value.
#>
[DscProperty()]
[string] $content
<#
This property reports the reasons the machine is or is not compliant.
[DscProperty(NotConfigurable)] attribute indicates the property is
not configurable in DSC configuration. Properties marked this way
are populated by the Get() method to report additional details
about the Resource when it is present.
#>
[DscProperty(NotConfigurable)]
[MyDscResourceReason[]] $Reasons
<#
This method is equivalent of the Get-TargetResource script function.
The implementation should use the keys to find appropriate
Resources. This method returns an instance of this class with the
updated key properties.
#>
[NewFile] Get() {
$get = Get-File -ensure $this.ensure -path $this.path -content $this.content
return $get
}
<#
This method is equivalent of the Set-TargetResource script function.
It sets the Resource to the desired state.
#>
[void] Set() {
$set = Set-File -ensure $this.ensure -path $this.path -content $this.content
}
<#
This method is equivalent of the Test-TargetResource script
function. It should return True or False, showing whether the
Resource is in a desired state.
#>
[bool] Test() {
$test = Test-File -ensure $this.ensure -path $this.path -content $this.content
return $test
}
}
إنشاء بيان
لتوفير مورد DSC المستند إلى الفئة، يجب تضمين عبارة DscResourcesToExport
في ملف البيان الذي يوجه الوحدة النمطية لتصدير مورد DSC. يبدو بياننا كما يلي:
@{
# Script module or binary module file associated with this manifest.
RootModule = 'NewFile.psm1'
# Version number of this module.
ModuleVersion = '1.0.0'
# ID used to uniquely identify this module
GUID = 'fad0d04e-65d9-4e87-aa17-39de1d008ee4'
# Author of this module
Author = 'Microsoft Corporation'
# Company or vendor of this module
CompanyName = 'Microsoft Corporation'
# Copyright statement for this module
Copyright = ''
# Description of the functionality provided by this module
Description = 'Create and set content of a file'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '5.0'
# Functions to export from this module
FunctionsToExport = @('Get-File','Set-File','Test-File')
# DSC Resources to export from this module
DscResourcesToExport = @('NewFile')
# Private data to pass to the module specified in RootModule/ModuleToProcess.
# This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
# Tags = @(Power Plan, Energy, Battery)
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
# ProjectUri = ''
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
# ReleaseNotes = ''
} # End of PSData hashtable
}
}
اختبار المورد
بعد حفظ ملفات الفئة والبيان في بنية المجلد الموضحة سابقا، يمكنك إنشاء تكوين DSC يستخدم مورد DSC الجديد. يتحقق التالي Configuration
لمعرفة ما إذا كان الملف /tmp/test.txt
موجودا وما إذا كانت المحتويات تتطابق مع السلسلة التي توفرها الخاصية Content. إذا لم يكن الأمر كما هو، تتم كتابة الملف بأكمله.
Configuration MyConfig {
Import-DSCResource -ModuleName NewFile
NewFile testFile {
Path = "/tmp/test.txt"
Content = "DSC Rocks!"
Ensure = "Present"
}
}
MyConfig
الإعلان عن موارد DSC متعددة تستند إلى الفئة في وحدة نمطية
يمكن للوحدة النمطية تحديد موارد DSC متعددة تستند إلى الفئة. تحتاج إلى تعريف جميع الفئات في نفس .psm1
الملف وتضمين كل اسم في .psd1
البيان.
$env:ProgramFiles\PowerShell\Modules (folder)
|- MyDscResource (folder)
|- MyDscResource.psm1
MyDscResource.psd1
راجع أيضاً
الملاحظات
https://aka.ms/ContentUserFeedback.
قريبًا: خلال عام 2024، سنتخلص تدريجيًا من GitHub Issues بوصفها آلية إرسال ملاحظات للمحتوى ونستبدلها بنظام ملاحظات جديد. لمزيد من المعلومات، راجعإرسال الملاحظات وعرضها المتعلقة بـ