{"id":11151,"date":"2015-10-01T07:22:00","date_gmt":"2015-10-01T07:22:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2015\/10\/01\/how-to-use-wmf-4-with-azure-dsc-extension-in-azure-cloud-service-manager-asm\/"},"modified":"2019-03-05T08:38:38","modified_gmt":"2019-03-05T16:38:38","slug":"how-to-use-wmf-4-with-azure-dsc-extension-in-azure-cloud-service-manager-asm","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/how-to-use-wmf-4-with-azure-dsc-extension-in-azure-cloud-service-manager-asm\/","title":{"rendered":"How to use WMF 4 with Azure DSC Extension in Azure Cloud Service Manager (ASM)"},"content":{"rendered":"<div class=\"markdown-body\">\n<h2>Overview<\/h2>\n<p>In version 2.7 of the Azure DSC Extension, we added support to leave your Virtual Machine on the latest supported version of WMF 4.0. This blog will show you how to use this feature in Azure Cloud Service Manager (ASM). This assumes you already know how to create a VM in the Azure PowerShell SDK. If you don&#8217;t please see <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/azure\/dn495254.aspx\">MSDN<\/a>. We are working to add this feature into the Azure Powershell SDK DSC extension Cmdlets directly. Currently, the WMF 4 feature is only available if you form the JSON yourself and send it to the extension using the generic extension Cmdlet.\nIn this Example I will show you:<\/p>\n<ol>\n<li>How to Create the JSON you need to send to the extension.<\/li>\n<li>How to create URI to published configuration which will only let people with this URI access it, known as the `ModulesUrl&#8217; to the extension.<\/li>\n<li>How to send this JSON to the extension on an existing VM.<\/li>\n<\/ol>\n<h2>Creating the JSON<\/h2>\n<p>To do this, use the <code>Set-AzureVMExtension<\/code> Cmdlet rather than the <code>Set-AzureVMDscExtension<\/code> Cmdlet and pass the JSON using the <code>-PublicConfiguration<\/code> parameter. The following function <code>New-XAzureVmDscExtensionJson<\/code> will create the JSON needed for this example.<\/p>\n<div class=\"highlight highlight-source-powershell\">\n<pre class=\"lang:default decode:true\"># Create a Json to send the the DSC VM Extension\r\nfunction New-XAzureVmDscExtensionJson\r\n{\r\n[CmdletBinding()]\r\n    param(\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [string]\r\n        $moduleName,\r\n        [Parameter(Mandatory = $false)]\r\n        [ValidateNotNull()]\r\n        [string]\r\n        $modulesUrl,\r\n        [AllowNull()]\r\n        [HashTable]\r\n        $properties,\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [string]\r\n        $configurationName,\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [ValidateSet('4.0','latest','5.0PP')]\r\n        [string]\r\n        $WmfVersion\r\n    )\r\n    $publicSettingsTable = @{\r\n        Properties = $properties\r\n        WmfVersion = $WmfVersion\r\n    }\r\n    if($null -ne $modulesUrl)\r\n    {\r\n      $publicSettingsTable.Add('ModulesUrl',$modulesUrl)\r\n    }\r\n    $publicSettingsTable.Add('ConfigurationFunction' , \"${ModuleName}\\${configurationName}\")\r\n    return ConvertTo-Json -Depth 8 $publicSettingsTable\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Here is an explanation of the values:<\/p>\n<ul>\n<li><code>modulesUrl<\/code>\n<ul>\n<li>Should be a URL to a zip file generated by <code>Publish-AzureVmDscConfiguration<\/code><\/li>\n<\/ul>\n<\/li>\n<li><code>moduleName<\/code>\n<ul>\n<li>The extension will look for this file name inside the zip file for the configuration.<\/li>\n<\/ul>\n<\/li>\n<li><code>configurationName<\/code>\n<ul>\n<li>The extension will look for a Configuration with this function inside the file\/module.<\/li>\n<\/ul>\n<\/li>\n<li><code>WmfVersion<\/code>\n<ul>\n<li>The version of WMF to upgrade or leave the machine on. Currently supported values:\n<ul>\n<li><code>4.0<\/code> indicating to upgrade to the currently supported version of WMF 4.0 if a newer version isn&#8217;t already installed.<\/li>\n<li><code>5.0PP<\/code> indicating to upgrade to the WMF 5.0PP.<\/li>\n<li><code>latest<\/code> indicating to upgrade to the latest version of WMF.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li><code>properties<\/code>\n<ul>\n<li>A Hash-table of parameters to be passed to the configuration<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>This function should produce a JSON that looks something like this.<\/p>\n<div class=\"highlight highlight-source-js\">\n<pre class=\"lang:default decode:true\">\"Properties\":  {\r\n                       \"DestinationPath\":  \"C:\\\\test\"\r\n                   },\r\n    \"WmfVersion\":  \"4.0\",\r\n    \"ConfigurationFunction\":  \"configuration.ps1\\\\ConfigurationName\",\r\n    \"ModulesUrl\":  \"https:\/\/storageaccountname.blob.core.windows.net\/windows-powershell-dsc\/configuration.ps1.zip?&lt;sastoken&gt;\"\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<h2>Creating the `ModulesUrl&#8217;<\/h2>\n<p>To generate the JSON, we need the <code>modulesUrl<\/code> this is the URL of the published configuration, with any querystring needed to access the URL. The following function <code>Get-XAzureDscPublishedModulesUrl<\/code> will publish the configuration, create a read-only SASToken for 1 hour, and return the full URI to the blob with the SASToken.<\/p>\n<div class=\"highlight highlight-source-powershell\">\n<pre class=\"lang:default decode:true\"># Publish a DSC configuration, Create a SasToken, and return the full URI with the SASToken\r\nfunction Get-XAzureDscPublishedModulesUrl\r\n{\r\n  [CmdletBinding()]\r\n  param\r\n  (\r\n    [Parameter(HelpMessage='The storage container to publish the configuration to')]\r\n    [ValidateNotNullOrEmpty()]\r\n    [String]\r\n    $StorageContainer  = 'windows-powershell-dsc',\r\n    [Parameter(Mandatory=$true, Position=0, HelpMessage='The name of the blob.')]\r\n    [ValidateNotNullOrEmpty()]\r\n    [String]\r\n    $blobName,\r\n    [Parameter(Mandatory=$true, Position=1, HelpMessage='The path to the configuration to publish')]\r\n    [ValidateNotNullOrEmpty()]\r\n    [String]\r\n    $configurationPath,\r\n    [Parameter(Mandatory=$true, Position=2, HelpMessage='The name of the storage account to publish to')]\r\n    [ValidateNotNullOrEmpty()]\r\n    [String]\r\n    $storageAccountName\r\n  )\r\n  # Get the Storage Account Context\r\n  function Get-AzureDscStorageAccountContext\r\n  {\r\n      param(\r\n        [Parameter(Mandatory=$true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [String]\r\n        $storageAccountName\r\n      )\r\n      $azureStorageAccount = Get-AzureStorageAccount -StorageAccountName $storageAccountName\r\n      if(!$azureStorageAccount)\r\n      {\r\n        throw 'storage account not found'\r\n      }\r\n      $storageAccessKey      = (Get-AzureStorageKey -StorageAccountName $StorageAccountName).Primary\r\n      $storageContext = New-AzureStorageContext -StorageAccountName $StorageAccountName `\r\n            -StorageAccountKey $storageAccessKey\r\n      return $storageContext\r\n  }\r\n  $expiryTime = [DateTime]::UtcNow.AddMinutes(60)\r\n  #Publish the configuration\r\n  Publish-AzureVMDscConfiguration -ConfigurationPath $configurationPath -Verbose -Force `\r\n      -storageContext (Get-AzureDscStorageAccountContext -storageAccountName $storageAccountName) `\r\n      -ContainerName $StorageContainer\r\n  # Create a SasToken for the Configuration\r\n  return New-AzureStorageBlobSASToken -Container $StorageContainer -Blob $blobName -Permission r `\r\n      -ExpiryTime $expiryTime -Context (Get-AzureDscStorageAccountContext -storageAccountName $storageAccountName) -FullUri\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<h2>Putting it all together and Sending it to a VM<\/h2>\n<p>Now we need to call the function to get the <code>modulesUrl<\/code>, pass the value to the function to get the JSON along with the rest of the parameters, get our VM object, and call <code>Set-AzureVMExtension<\/code> on the VM with the JSON and the parameter to send it the the DSC extension. The following is an example of how to do that.<\/p>\n<div class=\"highlight highlight-source-powershell\">\n<pre class=\"lang:default decode:true\">$storageAccountName = 'storageaccountname'\r\n$publisher          = 'Microsoft.Powershell'\r\n$dscVersion         = '2.7'\r\n$serviceName        = 'servicename'\r\n$vmName             = 'vmName'\r\n$moduleName         = 'configuration.ps1'\r\n$blobName           = \"$moduleName.zip\"\r\n$configurationPath  = \"$PSScriptRoot\\$moduleName\"\r\n$ConfigurationName  = 'ConfigurationName'\r\n$modulesUrl = Get-XAzureDscPublishedModulesUrl -blobName $blobName -configurationPath $configurationPath `\r\n   -storageAccountName $storageAccountName\r\nWrite-Verbose -Message \"ModulesUrl: $modulesUrl\" -Verbose\r\n$PublicConfigurationJson = New-XAzureVmDscExtensionJson -moduleName $moduleName -modulesUrl $modulesUrl `\r\n    -properties @{DestinationPath = 'C:\\test'} -configurationName $ConfigurationName -WmfVersion '4.0' -Verbose\r\nWrite-Verbose -Message \"PublicConfigurationJson: $PublicConfigurationJson\" -Verbose\r\n$vm = get-azurevm -ServiceName $serviceName -Name $vmName\r\n$vm = Set-AzureVMExtension `\r\n        -VM $vm `\r\n        -Publisher $publisher `\r\n        -ExtensionName 'DSC' `\r\n        -Version $dscVersion `\r\n        -PublicConfiguration $PublicConfigurationJson `\r\n        -ForceUpdate\r\n$vm | Update-Azure<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true \">VM<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>After the VM is finished update, you should have a WMF 4 VM. I&#8217;ll have a follow-up blog on how to do this in ARM.\nI have published these samples to <a href=\"https:\/\/github.com\/PowerShell\/PowerShell-Blog-Samples\/tree\/master\/2019-09-30-DSC-Extension-v2.7\/ASM\">GitHub<\/a> as a working script. Just update the, Service Name, etc. and run the script in the Azure PowerShell SDK.<\/p>\n<h2>Notes<\/h2>\n<p>Windows Server 2016 Technical Preview has the equivalent of WMF 5 already installed. Therefore, specifying WMF 4 for this OS is not a valid option.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Overview In version 2.7 of the Azure DSC Extension, we added support to leave your Virtual Machine on the latest supported version of WMF 4.0. This blog will show you how to use this feature in Azure Cloud Service Manager (ASM). This assumes you already know how to create a VM in the Azure PowerShell [&hellip;]<\/p>\n","protected":false},"author":604,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-11151","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell"],"acf":[],"blog_post_summary":"<p>Overview In version 2.7 of the Azure DSC Extension, we added support to leave your Virtual Machine on the latest supported version of WMF 4.0. This blog will show you how to use this feature in Azure Cloud Service Manager (ASM). This assumes you already know how to create a VM in the Azure PowerShell [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/11151","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/604"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=11151"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/11151\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=11151"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=11151"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=11151"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}