[15]Windows PowerShell DSC学习系列---基于.NET DLL(C#) 定制DSC资源?
2017-02-10 17:46
447 查看
我们知道我们在定制实现DSC的时候,其实现方式,既可以通过写PowerShell脚本实现,也可以通过写C#实现(DLL库),还可以通过类似于写Class风格的PowerShell脚本实现。本文笔者主要给大家介绍一下,如果通过C#代码来写实现。
生成后的MOF Schema(C:\Program Files\WindowsPowerShell\Modules\xSPAV\DSCResources\MSFT_XDemoFile\MSFT_XDemoFile.
schema.mof)的文件如下:
找到MSFT_XDemoFile.psm1文件并删除。
注意,我们需要引入System.Automation.Management.dll 这个DLL到项目中来。那么如何找到这个包呢?
在PowerShell的界面中执行下面的命令:Copy([PSObject].Assembly.Location) c:\Users\Admin\Desktop
就能把System.Automation.Management.dll 复制到桌面上,然后在Visutal Stuido导入进来即可。
打开MSFT_XDemoFile.cs文件,输入下面的内容。
编译成一个名字为MSFT_XDemoFile.dll类库;注意这个名字必须和MOF的名字保持一致。
MSFT_XDemoFile 目录下,下面是最终的相对目录结构。
测试脚本如下:
执行上面的脚本后,我们发现d:\DSC\test.txt文件里面的内容已经写成功。
参考文献:
https://msdn.microsoft.com/en-us/powershell/dsc/authoringresourcemofcs
@第1步:通过xDscResourceDesigner生成模板框架
首先通过x-DscResourceDesigner 模块中提供的cmdlet来自动生成MOF文件和相应的模板目录。New-xDscResource -ModuleName xCustomDemo -Name MSFT_XDemoFile -Path 'C:\Program Files\WindowsPowerShell\Modules' -FriendlyName 'MSFT_XDemoFile' -ClassVersion '0.9.0.0' -Property @( New-xDscResourceProperty -Name 'Path' -Type String -Attribute Key -Description 'path' New-xDscResourceProperty -Name 'Ensure' -Type String -Attribute Write -ValidateSet 'Present','Absent' -Description 'Should the file be present' New-xDscResourceProperty -Name 'Content' -Type String -Attribute Write -Description 'Contentof file.' ) -Force
生成后的MOF Schema(C:\Program Files\WindowsPowerShell\Modules\xSPAV\DSCResources\MSFT_XDemoFile\MSFT_XDemoFile.
schema.mof)的文件如下:
[ClassVersion("0.9.0.0"), FriendlyName("MSFT_XDemoFile")] class MSFT_XDemoFile : OMI_BaseResource { [Key, Description("path")] String Path; [Write, Description("Should the file be present"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Write, Description("Contentof file.")] String Content; };
@第2步:删除其生成的MSFT_XDemoFile.psm1
在下面的目录下:C:\Program Files\WindowsPowerShell\Modules\xSPAV\DSCResources\MSFT_XDemoFile\找到MSFT_XDemoFile.psm1文件并删除。
@第3步:写C#的实现代码
打开Visual Studio,然后新建一个Class Library的项目,其目录结构如下:注意,我们需要引入System.Automation.Management.dll 这个DLL到项目中来。那么如何找到这个包呢?
在PowerShell的界面中执行下面的命令:Copy([PSObject].Assembly.Location) c:\Users\Admin\Desktop
就能把System.Automation.Management.dll 复制到桌面上,然后在Visutal Stuido导入进来即可。
打开MSFT_XDemoFile.cs文件,输入下面的内容。
namespace cSharpDSCResourceExample { using System; using System.Collections.Generic; using System.IO; using System.Management.Automation; // Windows PowerShell assembly. #region Get-TargetResource [OutputType(typeof(System.Collections.Hashtable))] [Cmdlet(VerbsCommon.Get, "TargetResource")] public class GetTargetResource : PSCmdlet { [Parameter(Mandatory = true)] public string Path { get; set; } /// <summary> /// Implement the logic to return the current state of the resource as a hashtable with keys being the resource properties /// and the values are the corresponding current value on the machine. /// </summary> protected override void ProcessRecord() { var currentResourceState = new Dictionary<string, string>(); if (File.Exists(Path)) { currentResourceState.Add("Ensure", "Present"); // read current content string CurrentContent = ""; using (var reader = new StreamReader(Path)) { CurrentContent = reader.ReadToEnd(); } currentResourceState.Add("Content", CurrentContent); } else { currentResourceState.Add("Ensure", "Absent"); currentResourceState.Add("Content", ""); } // write the hashtable in the PS console. WriteObject(currentResourceState); } } # endregion #region Set-TargetResource [OutputType(typeof(void))] [Cmdlet(VerbsCommon.Set, "TargetResource")] public class SetTargetResource : PSCmdlet { [Parameter(Mandatory = true)] public string Path { get; set; } [Parameter(Mandatory = false)] [ValidateSet("Present", "Absent", IgnoreCase = true)] public string Ensure { get { // set the default to present. return (this._ensure ?? "Present"); } set { this._ensure = value; } } [Parameter(Mandatory = false)] public string Content { get { return (string.IsNullOrEmpty(this._content) ? "" : this._content); } set { this._content = value; } } private string _ensure; private string _content; /// <summary> /// Implement the logic to set the state of the machine to the desired state. /// </summary> protected override void ProcessRecord() { WriteVerbose(string.Format("Running set with parameters {0}{1}{2}", Path, Ensure, Content)); if (File.Exists(Path)) { if (Ensure.Equals("absent", StringComparison.InvariantCultureIgnoreCase)) { File.Delete(Path); } else { // file already exist and ensure "present" is specified. start writing the content to a file if (!string.IsNullOrEmpty(Content)) { string existingContent = null; using (var reader = new StreamReader(Path)) { existingContent = reader.ReadToEnd(); } // check if the content of the file mathes the content passed if (!existingContent.Equals(Content, StringComparison.InvariantCultureIgnoreCase)) { WriteVerbose("Existing content did not match with desired content updating the content of the file"); using (var writer = new StreamWriter(Path)) { writer.Write(Content); writer.Flush(); } } } } } else { if (Ensure.Equals("present", StringComparison.InvariantCultureIgnoreCase)) { // if nothing is passed for content just write "" otherwise write the content passed. using (var writer = new StreamWriter(Path)) { WriteVerbose(string.Format("Creating a file under path {0} with content {1}", Path, Content)); writer.Write(Content); } } } /* if you need to reboot the VM. please add the following two line of code. PSVariable DscMachineStatus = new PSVariable("DSCMachineStatus", 1, ScopedItemOptions.AllScope); this.SessionState.PSVariable.Set(DscMachineStatus); */ } } # endregion #region Test-TargetResource [Cmdlet("Test", "TargetResource")] [OutputType(typeof(Boolean))] public class TestTargetResource : PSCmdlet { [Parameter(Mandatory = true)] public string Path { get; set; } [Parameter(Mandatory = false)] [ValidateSet("Present", "Absent", IgnoreCase = true)] public string Ensure { get { // set the default to present. return (this._ensure ?? "Present"); } set { this._ensure = value; } } [Parameter(Mandatory = false)] public string Content { get { return (string.IsNullOrEmpty(this._content) ? "" : this._content); } set { this._content = value; } } private string _ensure; private string _content; /// <summary> /// Return a boolean value which indicates wheather the current machine is in desired state or not. /// </summary> protected override void ProcessRecord() { if (File.Exists(Path)) { if (Ensure.Equals("absent", StringComparison.InvariantCultureIgnoreCase)) { WriteObject(false); } else { // check if the content matches string existingContent = null; using (var stream = new StreamReader(Path)) { existingContent = stream.ReadToEnd(); } WriteObject(Content.Equals(existingContent, StringComparison.InvariantCultureIgnoreCase)); } } else { WriteObject(Ensure.Equals("Absent", StringComparison.InvariantCultureIgnoreCase)); } } } # endregion }
编译成一个名字为MSFT_XDemoFile.dll类库;注意这个名字必须和MOF的名字保持一致。
@第4步:部署MSFT_XDemoFile.dll
把MSFT_XDemoFile.dll类库拷贝到C:\Program Files\WindowsPowerShell\Modules\xCustomDemo\DSCResources\MSFT_XDemoFile 目录下,下面是最终的相对目录结构。
$env: psmodulepath (folder) |- xCustomDemo (folder) |- xCustomDemo.psd1 (file, required) |- DSCResources (folder) |- MSFT_XDemoFile (folder) |- MSFT_XDemoFile.psd1 (file, optional) |- MSFT_XDemoFile.dll (file, required) |- MSFT_XDemoFile.schema.mof (file, required)
@第5步:单元测试MSFT_XDemoFile DSC Resource
我们现在就可以测试MSFT_XDemoFile DSC资源中的Set和get方法了。测试脚本如下:
$result = Invoke-DscResource -Name MSFT_xDemoFile -Method Set -Property @{path="d:\DSC\test.txt" Ensure="Present" Content="Hello ggggg"} -Verbose $result| ft $result = Invoke-DscResource -Name MSFT_xDemoFile -Method Get -Property @{path="d:\DSC\test.txt" Ensure="Present" Content="Hello ggggg"} -Verbose $result| ft
@第6步:测试MSFT_XDemoFile配置是否生效
Configuration Test_CSharp_XDemo{ Import-DscResource -ModuleName xSPAV MSFT_xDemoFile test-xdemoFile{ path="d:\DSC\test.txt" Ensure="Present" Content="Hello World!!!!" } } Test_CSharp_XDemo Start-DscConfiguration -path .\Test_CSharp_XDemo -Wait -Force
执行上面的脚本后,我们发现d:\DSC\test.txt文件里面的内容已经写成功。
参考文献:
https://msdn.microsoft.com/en-us/powershell/dsc/authoringresourcemofcs
相关文章推荐
- [16]Windows PowerShell DSC学习系列---基于Class风格定制DSC资源?
- [11] Windows PowerShell DSC学习系列---如何定制一个基于PowerShell脚本实现的DSC Resource
- [13]Windows PowerShell DSC学习系列---直接调用DSC的资源方法
- [14]Windows PowerShell DSC学习系列---如何Debug PowerShell DSC?
- .Net学习难点讨论系列15 - 小技巧总结
- 学习C#和.NET的资源
- C#温故而知新学习系列之面向对象编程—15-对象初始化器
- Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作
- [2] Window PowerShell DSC 学习系列----DSC的资源(Resource)以及配置和格式(Configuration && Sytax )
- [17]Windows PowerShell DSC学习系列---使用WMI Tester调用msft-dsclocalconfigurationmanager类的方法
- [12]Windows PowerShell DSC学习系列---PowerShell DSC的几个例子
- C#温故而知新学习系列之.NET运行机制—.NET Framework概述及其组成(一)
- Nagios 监控系列学习 ―― check_nt 监控windows系统资源
- C#温故而知新学习系列之.NET运行机制—2-.NET中非托管代码是指什么?
- [21]Window PowerShell DSC学习系列---- 在Window 2012 R2 安装DSC 5.0 Pull服务器报错的解决方案
- .Net学习难点讨论系列2 – 细说C#中new关键字与多态
- C#温故而知新学习系列之.NET运行机制—.NET中托管代码是指什么?(三)
- C# 5.0 与 .Net 4.5 学习(一)Race Conditions资源竞争
- [25]Window PowerShell DSC学习系列----如何更换DSC Pull服务器数据库为Access数据库?