Merge-DscGallerySamplesToResourceModule.ps1
<#PSScriptInfo .VERSION 1.0.0 .GUID c9ce444b-9d19-4743-b674-6f15f86cade7 .AUTHOR Microsoft Corporation .COMPANYNAME Microsoft Corporation .COPYRIGHT 2018 (c) Microsoft Corporation. All rights reserved. .TAGS DSC,DesiredStateConfiguration .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES Version 1.0.0: First published version. #> <# .SYNOPSIS Merges all DSC samples as individual composite resources in a common resource module. .DESCRIPTION Merges all found DSC samples in PowerShell Gallery, authored by 'Microsoft Corporation' and has the tag 'DSCConfiguration', as individual composite resources into a common resource module. THe resource module is deployed to Azure Automation, together with the necessary dependent modules. .PARAMETER Subscription The subscription in which the automation account exist. This should be the subscription name or subscription id. .PARAMETER ResourceGroupName The name of the resource group in which the automation account exist. .PARAMETER AutomationAccountName The name of the automation to which to deploy the resource module and dependent modules. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.String] $Subscription, [Parameter(Mandatory = $true)] [System.String] $ResourceGroupName, [Parameter(Mandatory = $true)] [System.String] $AutomationAccountName, [Parameter()] [System.String] $ModuleName = 'CompositeModuleDsc', [Parameter()] [System.String] $ModuleVersion = '1.0.0', [Parameter(Mandatory = $true)] [System.Boolean] $AcceptLicense ) $azureRunAsConnection = Get-AutomationConnection -Name 'AzureRunAsConnection' $connectAzureRmAccountParameters = @{ ServicePrincipal = $true Tenant = $azureRunAsConnection.TenantID ApplicationID = $azureRunAsConnection.ApplicationID CertificateThumbprint = $azureRunAsConnection.CertificateThumbprint Subscription = $Subscription } Write-Verbose -Message 'Connecting to Azure subscription.' -Verbose Connect-AzureRmAccount @connectAzureRmAccountParameters Write-Verbose -Message 'Finding and saving all DSC sample scripts in PowerShell Gallery. This can take a while.' -Verbose $galleryScripts = Find-Script -Tag 'DSCConfiguration' | Where-Object -FilterScript { $_.Author -eq 'Microsoft Corporation' } if ($galleryScripts) { $galleryScripts | Save-Script -Path '.\Scripts' -Force -AcceptLicense:$AcceptLicense $sampleConfigurations = Get-ChildItem -Path '.\Scripts\*' -Filter '*.ps1' foreach ($sampleConfiguration in $sampleConfigurations) { $scriptName = (Split-Path -Path $sampleConfiguration.FullName -Leaf) Write-Verbose -Message ('Converting script: {0}' -f $scriptName) -Verbose $script = Get-Content -Path $sampleConfiguration.FullName -Raw $convertToCompositeResourceParameters = @{ Script = $script ModuleName = $ModuleName ModuleVersion = $ModuleVersion OutputPath = '.\Module' } ConvertTo-CompositeResource @convertToCompositeResourceParameters } $archiveSourcePath = Join-Path -Path (Join-Path -Path '.\Module' -ChildPath $ModuleName) -ChildPath $ModuleVersion $archiveDestinationPath = Join-Path -Path '.' -ChildPath "$ModuleName.zip" Write-Verbose -Message 'Compressing module into a archive.' -Verbose Compress-Archive -Path $archiveSourcePath -DestinationPath $archiveDestinationPath -Force # Use the first 24 chars of a guid (after it is stripped of dashes). $storageAccountName = ((New-Guid) -replace '-').Substring(1, 24) $storageAccountLocation = (Get-AzureRmResourceGroup -ResourceGroupName $ResourceGroupName).Location try { Write-Verbose -Message ('Creating temporary storage account ''{0}'' in the location ''{1}'', inside the resource group ''{2}'', for temporary storage of the module archive.' -f $storageAccountName, $storageAccountLocation, $ResourceGroupName) -Verbose $newAzureRmStorageAccountParameters = @{ ResourceGroupName = $ResourceGroupName Name = $storageAccountName Location = $storageAccountLocation SkuName = 'Standard_LRS' Kind = 'BlobStorage' AccessTier = 'Hot' } $newAzureRmStorageAccountResult = New-AzureRmStorageAccount @newAzureRmStorageAccountParameters $storageContainerName = 'tempmoduleupload' Write-Verbose -Message ('Creating storage container ''{0}'' in the storage account ''{1}''.' -f $storageContainerName, $storageAccountName) -Verbose $newAzureStorageContainerParameters = @{ Name = $storageContainerName Context = $newAzureRmStorageAccountResult.Context Permission = 'Blob' } $newAzureStorageContainerResult = New-AzureStorageContainer @newAzureStorageContainerParameters Write-Verbose -Message ('Uploading module archive ''{0}'' to storage container ''{1}'' in the storage account ''{2}''.' -f $archiveDestinationPath, $storageContainerName, $storageAccountName) -Verbose $setAzureStorageBlobContentParameters = @{ Context = $newAzureRmStorageAccountResult.Context Container = $storageContainerName File = $archiveDestinationPath Blob = "$ModuleName.zip" Force = $true } $blobObject = Set-AzureStorageBlobContent @setAzureStorageBlobContentParameters Write-Verbose -Message ('Importing composite module ''{0}'' into automation account ''{1}'' from storage container URI ''{2}''.' -f $ModuleName, $AutomationAccountName, $blobObject.ICloudBlob.Uri.AbsoluteUri) -Verbose $newAzureRmAutomationModuleParameters = @{ ResourceGroupName = $ResourceGroupName AutomationAccountName = $AutomationAccountName Name = $ModuleName ContentLinkUri = $blobObject.ICloudBlob.Uri.AbsoluteUri } New-AzureRmAutomationModule @newAzureRmAutomationModuleParameters | Out-Null $getAzureRmAutomationModuleParameters = @{ ResourceGroupName = $ResourceGroupName AutomationAccountName = $AutomationAccountName Name = $ModuleName } $timeoutCounter = 0 do { $timeoutCounter++ if ($timeoutCounter -eq 5) { Write-Verbose -Message ('Waiting for import of module ''{0}'' to automation account ''{1}'' to finish.' -f $ModuleName, $AutomationAccountName) -Verbose } Start-Sleep -Seconds 40 $compositeResourceModule = Get-AzureRmAutomationModule @getAzureRmAutomationModuleParameters } until ($compositeResourceModule.ProvisioningState -eq 'Succeeded' -or $timeoutCounter -gt 10) if ($timeoutCounter -gt 10) { throw 'The module ''{0}'' was not deployed within the timeout period.' -f $ModuleName } else { Write-Verbose -Message ('Composite module ''{0}'' was successfully imported into automation account ''{1}''.' -f $ModuleName, $AutomationAccountName) -Verbose } } catch { throw $_ } finally { $getAzureRmStorageAccountResult = Get-AzureRmStorageAccount -Name $storageAccountName -ResourceGroupName $ResourceGroupName -ErrorAction 'SilentlyContinue' if ($getAzureRmStorageAccountResult) { Write-Verbose -Message ('Removing temporary storage account ''{0}'' , from the resource group ''{1}''.' -f $storageAccountName, $ResourceGroupName) -Verbose $getAzureRmStorageAccountResult | Remove-AzureRmStorageAccount -Force } } } else { throw 'Could not find any scripts in the Gallery with the specified criteria.' } |