[16]Windows PowerShell DSC学习系列---基于Class风格定制DSC资源?

原创 2017年02月13日 13:57:41

前面的章节介绍了,[15]Windows PowerShell DSC学习系列---基于.NET DLL(C#) 定制DSC资源?
[11] Windows PowerShell DSC学习系列---如何定制一个基于PowerShell脚本实现的DSC Resource,这一节来的更奇妙的;我们知道根据我们以往的经验,一个开发平台或者一个开发语言,随着版本的更新和发展,其提供的功能会变得越来越强大,越来越方便简单;DSC框架也不例外,在PowerShell DSC 5.0的版本开始,其提供了更多简单的DSC 资源的定制方式,也更加灵活了;其可以让开发者直接编写基于面向对象的类的方式去定制DSC的资源,而且其文件结构也更为简单,已经不需要一定放在DSCResource子文件夹下了。也不需要MOF文件去定义其Schema了,因为其输入参数可以合并到DSC实现类里面一起定义。

本文参考https://msdn.microsoft.com/en-us/powershell/dsc/authoringresourceclass,下面简单介绍一下其具体的实施步骤。

笔者以一个简单的文件拷贝的DSC资源为例子。文件结构如下:


@编写基于DSC Class风格的MyDscResource.psm1的实现

enum Ensure
{
    Absent
    Present
}

<#
   This resource manages the file in a specific path.
   [DscResource()] indicates the class is a DSC resource
#>

[DscResource()]
class FileResource
{
    <#
       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 defines the fully qualified path to a file that will
       be placed on the system if $Ensure = Present and $Path does not
        exist.

       NOTE: This property is required because [DscProperty(Mandatory)] is
        set.
    #>
    [DscProperty(Mandatory)]
    [string] $SourcePath

    <#
       This property reports the file's create timestamp.

       [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)]
    [Nullable[datetime]] $CreationTime

    <#
        This method is equivalent of the Set-TargetResource script function.
        It sets the resource to the desired state.
    #>
    [void] Set()
    {
        Write-Verbose -Message "11111111----Begin to invoke Set()------11111111"
        $fileExists = $this.TestFilePath($this.Path)
        if ($this.ensure -eq [Ensure]::Present)
        {
            if (-not $fileExists)
            {
                $this.CopyFile()
            }
        }
        else
        {
            if ($fileExists)
            {
                Write-Verbose -Message "Deleting the file $($this.Path)"
                Remove-Item -LiteralPath $this.Path -Force
            }
        }
        Write-Verbose -Message "11111111----End to invoke Set()------11111111"
    }

    <#
        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()
    {
        Write-Verbose -Message "11111111----Begin to invoke Test()------11111111"
        $present = $this.TestFilePath($this.Path)

        if ($this.Ensure -eq [Ensure]::Present)
        {
           Write-Verbose -Message "11111111----End to invoke Test()------11111111:$present"
            return $present
        }
        else
        {
             Write-Verbose -Message "11111111----End to invoke Test()------11111111:$present"
            return -not $present
        }
        
    }

    <#
        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.
    #>
    [FileResource] Get()

    {
         Write-Verbose -Message "11111111----Begin to invoke Get()------11111111"
        $present = $this.TestFilePath($this.Path)

        if ($present)
        {
            $file = Get-ChildItem -LiteralPath $this.Path
            $this.CreationTime = $file.CreationTime
            $this.Ensure = [Ensure]::Present
        }
        else
        {
            $this.CreationTime = $null
            $this.Ensure = [Ensure]::Absent
        }
         Write-Verbose -Message "11111111----End to invoke Get()------11111111"
        return $this
    }

    <#
        Helper method to check if the file exists and it is file
    #>
    [bool] TestFilePath([string] $location)
    {
        $present = $true

        $item = Get-ChildItem -LiteralPath $location -ea Ignore
        if ($item -eq $null)
        {
            $present = $false
        }
        elseif ($item.PSProvider.Name -ne "FileSystem")
        {
            throw "Path $($location) is not a file path."
        }
        elseif ($item.PSIsContainer)
        {
            throw "Path $($location) is a directory path."
        }

        return $present
    }

    <#
        Helper method to copy file from source to path
    #>
    [void] CopyFile()
    {
        if (-not $this.TestFilePath($this.SourcePath))
        {
            throw "SourcePath $($this.SourcePath) is not found."
        }

        [System.IO.FileInfo] $destFileInfo = new-object System.IO.FileInfo($this.Path)
        if (-not $destFileInfo.Directory.Exists)
        {
            Write-Verbose -Message "Creating directory $($destFileInfo.Directory.FullName)"

            <#
                Use CreateDirectory instead of New-Item to avoid code
                 to handle the non-terminating error
            #>
            [System.IO.Directory]::CreateDirectory($destFileInfo.Directory.FullName)
        }

        if (Test-Path -LiteralPath $this.Path -PathType Container)
        {
            throw "Path $($this.Path) is a directory path"
        }

        Write-Verbose -Message "Copying $($this.SourcePath) to $($this.Path)"

        # DSC engine catches and reports any error that occurs
        Copy-Item -LiteralPath $this.SourcePath -Destination $this.Path -Force
    }
} # This module defines a class for a DSC "FileResource" provider.


@编写MyDscResource的资源模块描述文件

@{
# Script module or binary module file associated with this manifest.
RootModule = 'MyDscResource.psm1'
DscResourcesToExport = 'FileResource'
# Version number of this module.
ModuleVersion = '1.0.1'
# ID used to uniquely identify this module
GUID = '81624038-5e71-40f8-8905-b1a87afe22d7'
# Author of this module
Author = 'Microsoft Corporation'
# Company or vendor of this module
CompanyName = 'Microsoft Corporation'
# Copyright statement for this module
Copyright = '(c) 2014 Microsoft. All rights reserved.'
# Description of the functionality provided by this module
# Description = ''
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '5.0'
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
}

@确认定制资源十分生效

在PowerShell控制台,运行get-dscResource,可以看到起已经生效。


@运行测试文件

测试文件TestFileResouce的PowerShell脚本如下:
Configuration TestFileResource
{
    Import-DSCResource -module MyDscResource
    FileResource file
    {
        Path = "d:\dsc\vvvv.txt"
        SourcePath = "d:\dsc\1111.txt"
        Ensure = "Present"
    } 
}
TestFileResource
Start-DscConfiguration  -Wait -Force -verbose TestFileResource

其输出结果如下,命令运行成功~!!!:
PS D:\DSC> Start-DscConfiguration  -Wait -Force -verbose TestFileResource
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root
/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer example-test with user sid S-1-5-21-1801674531-602162358-2146502713-16690.
VERBOSE: [example-test]: LCM:  [ Start  Set      ]
VERBOSE: [example-test]:                            [DSCEngine] Importing the module C:\Program Files\WindowsPowerShell\Modules\MyDscResource\MyDscResource.psd1 in force mode.
VERBOSE: [example-test]: LCM:  [ Start  Resource ]  [[FileResource]file]
VERBOSE: [example-test]: LCM:  [ Start  Test     ]  [[FileResource]file]
VERBOSE: [example-test]:                            [[FileResource]file] Importing the module MyDscResource in force mode.
VERBOSE: [example-test]:                            [[FileResource]file] 11111111----Begin to invoke Test()------11111111
VERBOSE: [example-test]:                            [[FileResource]file] 11111111----End to invoke Test()------11111111:False
VERBOSE: [example-test]: LCM:  [ End    Test     ]  [[FileResource]file]  in 0.0360 seconds.
VERBOSE: [example-test]: LCM:  [ Start  Set      ]  [[FileResource]file]
VERBOSE: [example-test]:                            [[FileResource]file] Importing the module MyDscResource in force mode.
VERBOSE: [example-test]:                            [[FileResource]file] 11111111----Begin to invoke Set()------11111111
VERBOSE: [example-test]:                            [[FileResource]file] Copying d:\dsc\1111.txt to d:\dsc\vvvv.txt
VERBOSE: [example-test]:                            [[FileResource]file] 11111111----End to invoke Set()------11111111
VERBOSE: [example-test]: LCM:  [ End    Set      ]  [[FileResource]file]  in 0.0400 seconds.
VERBOSE: [example-test]: LCM:  [ End    Resource ]  [[FileResource]file]
VERBOSE: [example-test]: LCM:  [ End    Set      ]
VERBOSE: [example-test]: LCM:  [ End    Set      ]    in  0.1280 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 0.168 seconds

如果想Debug,请运行Enable-DscDebug -BreakAll
如果想取消DSC的资源的Debug,请运行Disable-DscDebug




版权声明:本文为博主原创文章,未经博主允许不得转载。

[17]Windows PowerShell DSC学习系列---使用WMI Tester调用msft-dsclocalconfigurationmanager类的方法

在这边文章中,其列出了DSC中的本地配置管理引擎中的msft-dsclocalconfigurationmanager类,其列出了这个类中的很多方法。比如GetConfigurationStatus,...

[24]Window PowerShell DSC学习系列---- 如何保护MOF文件里面存储的密码?

在上节笔者分享了[23]Window PowerShell DSC学习系列---- MOF文件能存储用户的密码吗?MOF文件里面能直接存储明文密码,这样是非常不安全的。那么有什么方式能够把MOF里面存...

[23]Window PowerShell DSC学习系列---- MOF文件能存储用户的密码吗?

我们知道,DSC的资源中,有很多的资源是需要访问文件共享目录,进入本地的用户的目录,或者为一个特定的用户安装一个MSI的安装包,修改注册表;这个时候,如果直接执行调用DSC的资源,则可能会弹出“Acc...

[26]Window PowerShell DSC学习系列----如何更换Pull服务器数据库为SQL Server数据库

上节我们提到了如何把PowerShell DSC的数据库换成Access;DSC Pull服务器当前的版本对MS SQL Server是不支持的,该怎么办?另外如果我们需要对Pull服务器建立负载均衡...

[10] Window PowerShell DSC 学习系列----目标节点和Pull 服务器底层通信原理剖析

在本节中,笔者将会用wireshark抓包,并分析目标节点如何和Pull 服务器通信的?注意笔者本机装的Window Management Framework 5.1,如果是其他的版本,可能请求的UR...

[7] Window PowerShell DSC 学习系列----如何被管理的设置节点注册到Pull Server?

在上一节,[6] Window PowerShell DSC 学习系列----如何安装最新的PowerShell DSC 5.1 Pull Server?笔者聊到了如何安装Pull Server。那么...

[20]Window PowerShell DSC学习系列---- start-dscconfiguration 中遇到 Access Denied的解决方案

当我们执行start-DscConfiguration -computername psdsc-window201 -Path c:\DSC\TestFile -Wait -Verbose -forc...

[9] Window PowerShell DSC 学习系列----错误诊断和分析

PowerShell DSC就像一个汽车,内部复杂,司机作为一个普通的用户在使用它,因为知道一些汽车的基本常识,所以当汽车发生一些简单的故障时,可以通过汽车自身带的仪表仪器诊断问题出在哪方面,也可以借...

[2] Window PowerShell DSC 学习系列----DSC的资源(Resource)以及配置和格式(Configuration && Sytax )

这个章节主要来讲述DSC的资源(Resource)以及配置和格式(Configuration && Sytax )。...

[25]Window PowerShell DSC学习系列----如何更换DSC Pull服务器数据库为Access数据库?

我们知道,PowerShell DSC的默认数据库为ESENT文件数据库;或者oleDB形式的Access数据库(数据库文件后缀名为:mdb). 默认安装方式下,如果用xDscWebService D...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[16]Windows PowerShell DSC学习系列---基于Class风格定制DSC资源?
举报原因:
原因补充:

(最多只允许输入30个字)