├── TestDSC.zip
├── ChangeCDLetter.zip
├── ChangeDriveLabel.zip
├── ChangeDriveLabel.ps1
├── README.md
├── TestDSC.ps1
├── azuredeploy.parameters.json
├── ProdataARM.sln
├── ProdataARM.deployproj
├── .gitattributes
├── .gitignore
├── Deployment.targets
├── Deploy-AzureResourceGroup.ps1
└── azuredeploy.json
/TestDSC.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProdataSQL/ProdataARM/master/TestDSC.zip
--------------------------------------------------------------------------------
/ChangeCDLetter.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProdataSQL/ProdataARM/master/ChangeCDLetter.zip
--------------------------------------------------------------------------------
/ChangeDriveLabel.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProdataSQL/ProdataARM/master/ChangeDriveLabel.zip
--------------------------------------------------------------------------------
/ChangeDriveLabel.ps1:
--------------------------------------------------------------------------------
1 | Configuration ChangeLabel
2 | {
3 | Node localhost
4 | {
5 | drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'F:'"
6 | $drive.Label = "Label:"
7 | $drive.put()
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Click the button below to deploy
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/TestDSC.ps1:
--------------------------------------------------------------------------------
1 | Configuration FileResourceDemo
2 | {
3 | Node "localhost"
4 | {
5 | File CreateFile {
6 | DestinationPath = 'C:\Temp\Test.txt'
7 | Ensure = "Present"
8 | Contents = 'Hello World!'
9 | }
10 |
11 | Log AfterDirectoryCopy
12 | {
13 | # The message below gets written to the Microsoft-Windows-Desired State Configuration/Analytic log
14 | Message = "Finished running the file resource with ID CreateFile"
15 | DependsOn = "[File]CreateFile" # This means run "CreateFile" first.
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/azuredeploy.parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "adminUsername": {
6 | "value": "Esteban"
7 | },
8 | "adminPassword": {
9 | "value": "Password1234"
10 | },
11 | "vmName": {
12 | "value": "EstebanVM"
13 | },
14 | "vmSize": {
15 | "value": "Standard_D3"
16 | },
17 | "sizeOf_E_Drive": {
18 | "value": "100"
19 | },
20 | "StorageType": {
21 | "value": "Premium_LRS"
22 | },
23 | "DiskCaching": {
24 | "value": "ReadOnly"
25 | },
26 | "IPAddressesType": {
27 | "value": "Static"
28 | },
29 | "IPAdress": {
30 | "value": "10.0.0.4"
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/ProdataARM.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{151D2E53-A2C4-4D7D-83FE-D05416EBD58E}") = "ProdataARM", "ProdataARM.deployproj", "{AE8BDA41-2ABE-4908-862E-B30EBBD74156}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {AE8BDA41-2ABE-4908-862E-B30EBBD74156}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {AE8BDA41-2ABE-4908-862E-B30EBBD74156}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {AE8BDA41-2ABE-4908-862E-B30EBBD74156}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {AE8BDA41-2ABE-4908-862E-B30EBBD74156}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/ProdataARM.deployproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 |
8 |
9 | Release
10 | AnyCPU
11 |
12 |
13 |
14 | ae8bda41-2abe-4908-862e-b30ebbd74156
15 |
16 |
17 | Deployment
18 | 1.0
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | False
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | [Xx]64/
19 | [Xx]86/
20 | [Bb]uild/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 | *.VC.db
84 |
85 | # Visual Studio profiler
86 | *.psess
87 | *.vsp
88 | *.vspx
89 | *.sap
90 |
91 | # TFS 2012 Local Workspace
92 | $tf/
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 | *.DotSettings.user
101 |
102 | # JustCode is a .NET coding add-in
103 | .JustCode
104 |
105 | # TeamCity is a build add-in
106 | _TeamCity*
107 |
108 | # DotCover is a Code Coverage Tool
109 | *.dotCover
110 |
111 | # NCrunch
112 | _NCrunch_*
113 | .*crunch*.local.xml
114 | nCrunchTemp_*
115 |
116 | # MightyMoose
117 | *.mm.*
118 | AutoTest.Net/
119 |
120 | # Web workbench (sass)
121 | .sass-cache/
122 |
123 | # Installshield output folder
124 | [Ee]xpress/
125 |
126 | # DocProject is a documentation generator add-in
127 | DocProject/buildhelp/
128 | DocProject/Help/*.HxT
129 | DocProject/Help/*.HxC
130 | DocProject/Help/*.hhc
131 | DocProject/Help/*.hhk
132 | DocProject/Help/*.hhp
133 | DocProject/Help/Html2
134 | DocProject/Help/html
135 |
136 | # Click-Once directory
137 | publish/
138 |
139 | # Publish Web Output
140 | *.[Pp]ublish.xml
141 | *.azurePubxml
142 |
143 | # TODO: Un-comment the next line if you do not want to checkin
144 | # your web deploy settings because they may include unencrypted
145 | # passwords
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # NuGet Packages
150 | *.nupkg
151 | # The packages folder can be ignored because of Package Restore
152 | **/packages/*
153 | # except build/, which is used as an MSBuild target.
154 | !**/packages/build/
155 | # Uncomment if necessary however generally it will be regenerated when needed
156 | #!**/packages/repositories.config
157 | # NuGet v3's project.json files produces more ignoreable files
158 | *.nuget.props
159 | *.nuget.targets
160 |
161 | # Microsoft Azure Build Output
162 | csx/
163 | *.build.csdef
164 |
165 | # Microsoft Azure Emulator
166 | ecf/
167 | rcf/
168 |
169 | # Windows Store app package directory
170 | AppPackages/
171 | BundleArtifacts/
172 |
173 | # Visual Studio cache files
174 | # files ending in .cache can be ignored
175 | *.[Cc]ache
176 | # but keep track of directories ending in .cache
177 | !*.[Cc]ache/
178 |
179 | # Others
180 | ClientBin/
181 | [Ss]tyle[Cc]op.*
182 | ~$*
183 | *~
184 | *.dbmdl
185 | *.dbproj.schemaview
186 | *.pfx
187 | *.publishsettings
188 | node_modules/
189 | orleans.codegen.cs
190 |
191 | # RIA/Silverlight projects
192 | Generated_Code/
193 |
194 | # Backup & report files from converting an old project file
195 | # to a newer Visual Studio version. Backup files are not needed,
196 | # because we have git ;-)
197 | _UpgradeReport_Files/
198 | Backup*/
199 | UpgradeLog*.XML
200 | UpgradeLog*.htm
201 |
202 | # SQL Server files
203 | *.mdf
204 | *.ldf
205 |
206 | # Business Intelligence projects
207 | *.rdl.data
208 | *.bim.layout
209 | *.bim_*.settings
210 |
211 | # Microsoft Fakes
212 | FakesAssemblies/
213 |
214 | # GhostDoc plugin setting file
215 | *.GhostDoc.xml
216 |
217 | # Node.js Tools for Visual Studio
218 | .ntvs_analysis.dat
219 |
220 | # Visual Studio 6 build log
221 | *.plg
222 |
223 | # Visual Studio 6 workspace options file
224 | *.opt
225 |
226 | # Visual Studio LightSwitch build output
227 | **/*.HTMLClient/GeneratedArtifacts
228 | **/*.DesktopClient/GeneratedArtifacts
229 | **/*.DesktopClient/ModelManifest.xml
230 | **/*.Server/GeneratedArtifacts
231 | **/*.Server/ModelManifest.xml
232 | _Pvt_Extensions
233 |
234 | # LightSwitch generated files
235 | GeneratedArtifacts/
236 | ModelManifest.xml
237 |
238 | # Paket dependency manager
239 | .paket/paket.exe
240 |
241 | # FAKE - F# Make
242 | .fake/
243 | /ProdataARM/
244 |
--------------------------------------------------------------------------------
/Deployment.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | bin\$(Configuration)\
7 | false
8 | true
9 | false
10 | None
11 | obj\
12 | $(BaseIntermediateOutputPath)\
13 | $(BaseIntermediateOutputPath)$(Configuration)\
14 | $(IntermediateOutputPath)ProjectReferences
15 | $(ProjectReferencesOutputPath)\
16 | true
17 |
18 |
19 |
20 | false
21 | false
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | Always
33 |
34 |
35 | Never
36 |
37 |
38 | false
39 | Build
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | _GetDeploymentProjectContent;
48 | _CalculateContentOutputRelativePaths;
49 | _GetReferencedProjectsOutput;
50 | _CalculateArtifactStagingDirectory;
51 | _CopyOutputToArtifactStagingDirectory;
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | Configuration=$(Configuration);Platform=$(Platform)
69 |
70 |
71 |
75 |
76 |
77 |
78 | $([System.IO.Path]::GetFileNameWithoutExtension('%(ProjectReference.Identity)'))
79 |
80 |
81 |
82 |
83 |
84 |
85 | $(OutDir)
86 | $(OutputPath)
87 | $(ArtifactStagingDirectory)\
88 | $(ArtifactStagingDirectory)staging\
89 | $(Build_StagingDirectory)
90 |
91 |
92 |
93 |
94 |
96 |
97 | <_OriginalIdentity>%(DeploymentProjectContentOutput.Identity)
98 | <_RelativePath>$(_OriginalIdentity.Replace('$(MSBuildProjectDirectory)', ''))
99 |
100 |
101 |
102 |
103 | $(_RelativePath)
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | PrepareForRun
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/Deploy-AzureResourceGroup.ps1:
--------------------------------------------------------------------------------
1 | #Requires -Version 3.0
2 | #Requires -Module AzureRM.Resources
3 | #Requires -Module Azure.Storage
4 |
5 | Param(
6 | [string] [Parameter(Mandatory=$true)] $ResourceGroupLocation,
7 | [string] $ResourceGroupName = 'MusgraveAzure',
8 | [switch] $UploadArtifacts,
9 | [string] $StorageAccountName,
10 | [string] $StorageContainerName = $ResourceGroupName.ToLowerInvariant() + '-stageartifacts',
11 | [string] $TemplateFile = 'azuredeploy.json',
12 | [string] $TemplateParametersFile = 'azuredeploy.parameters.json',
13 | [string] $ArtifactStagingDirectory = '.',
14 | [string] $DSCSourceFolder = 'DSC',
15 | [switch] $ValidateOnly
16 | )
17 |
18 | Import-Module Azure -ErrorAction SilentlyContinue
19 |
20 | try {
21 | [Microsoft.Azure.Common.Authentication.AzureSession]::ClientFactory.AddUserAgent("VSAzureTools-$UI$($host.name)".replace(" ","_"), "2.9.6")
22 | } catch { }
23 |
24 | Set-StrictMode -Version 3
25 |
26 | function Format-ValidationOutput {
27 | param ($ValidationOutput, [int] $Depth = 0)
28 | Set-StrictMode -Off
29 | return @($ValidationOutput | Where-Object { $_ -ne $null } | ForEach-Object { @(" " * $Depth + $_.Code + ": " + $_.Message) + @(Format-ValidationOutput @($_.Details) ($Depth + 1)) })
30 | }
31 |
32 | $OptionalParameters = New-Object -TypeName Hashtable
33 | $TemplateFile = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $TemplateFile))
34 | $TemplateParametersFile = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $TemplateParametersFile))
35 |
36 | if ($UploadArtifacts) {
37 | # Convert relative paths to absolute paths if needed
38 | $ArtifactStagingDirectory = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $ArtifactStagingDirectory))
39 | $DSCSourceFolder = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $DSCSourceFolder))
40 |
41 | Set-Variable ArtifactsLocationName '_artifactsLocation' -Option ReadOnly -Force
42 | Set-Variable ArtifactsLocationSasTokenName '_artifactsLocationSasToken' -Option ReadOnly -Force
43 |
44 | $OptionalParameters.Add($ArtifactsLocationName, $null)
45 | $OptionalParameters.Add($ArtifactsLocationSasTokenName, $null)
46 |
47 | # Parse the parameter file and update the values of artifacts location and artifacts location SAS token if they are present
48 | $JsonContent = Get-Content $TemplateParametersFile -Raw | ConvertFrom-Json
49 | $JsonParameters = $JsonContent | Get-Member -Type NoteProperty | Where-Object {$_.Name -eq "parameters"}
50 |
51 | if ($JsonParameters -eq $null) {
52 | $JsonParameters = $JsonContent
53 | }
54 | else {
55 | $JsonParameters = $JsonContent.parameters
56 | }
57 |
58 | $JsonParameters | Get-Member -Type NoteProperty | ForEach-Object {
59 | $ParameterValue = $JsonParameters | Select-Object -ExpandProperty $_.Name
60 |
61 | if ($_.Name -eq $ArtifactsLocationName -or $_.Name -eq $ArtifactsLocationSasTokenName) {
62 | $OptionalParameters[$_.Name] = $ParameterValue.value
63 | }
64 | }
65 |
66 | # Create DSC configuration archive
67 | if (Test-Path $DSCSourceFolder) {
68 | $DSCSourceFilePaths = @(Get-ChildItem $DSCSourceFolder -File -Filter "*.ps1" | ForEach-Object -Process {$_.FullName})
69 | foreach ($DSCSourceFilePath in $DSCSourceFilePaths) {
70 | $DSCArchiveFilePath = $DSCSourceFilePath.Substring(0, $DSCSourceFilePath.Length - 4) + ".zip"
71 | Publish-AzureRmVMDscConfiguration $DSCSourceFilePath -OutputArchivePath $DSCArchiveFilePath -Force -Verbose
72 | }
73 | }
74 |
75 | # Create a storage account name if none was provided
76 | if($StorageAccountName -eq "") {
77 | $subscriptionId = ((Get-AzureRmContext).Subscription.SubscriptionId).Replace('-', '').substring(0, 19)
78 | $StorageAccountName = "stage$subscriptionId"
79 | }
80 |
81 | $StorageAccount = (Get-AzureRmStorageAccount | Where-Object{$_.StorageAccountName -eq $StorageAccountName})
82 |
83 | # Create the storage account if it doesn't already exist
84 | if($StorageAccount -eq $null){
85 | $StorageResourceGroupName = "ARM_Deploy_Staging"
86 | New-AzureRmResourceGroup -Location "$ResourceGroupLocation" -Name $StorageResourceGroupName -Force
87 | $StorageAccount = New-AzureRmStorageAccount -StorageAccountName $StorageAccountName -Type 'Standard_LRS' -ResourceGroupName $StorageResourceGroupName -Location "$ResourceGroupLocation"
88 | }
89 |
90 | $StorageAccountContext = (Get-AzureRmStorageAccount | Where-Object{$_.StorageAccountName -eq $StorageAccountName}).Context
91 |
92 | # Generate the value for artifacts location if it is not provided in the parameter file
93 | $ArtifactsLocation = $OptionalParameters[$ArtifactsLocationName]
94 | if ($ArtifactsLocation -eq $null) {
95 | $ArtifactsLocation = $StorageAccountContext.BlobEndPoint + $StorageContainerName
96 | $OptionalParameters[$ArtifactsLocationName] = $ArtifactsLocation
97 | }
98 |
99 | # Copy files from the local storage staging location to the storage account container
100 | New-AzureStorageContainer -Name $StorageContainerName -Context $StorageAccountContext -ErrorAction SilentlyContinue *>&1
101 |
102 | $ArtifactFilePaths = Get-ChildItem $ArtifactStagingDirectory -Recurse -File | ForEach-Object -Process {$_.FullName}
103 | foreach ($SourcePath in $ArtifactFilePaths) {
104 | $BlobName = $SourcePath.Substring($ArtifactStagingDirectory.length + 1)
105 | Set-AzureStorageBlobContent -File $SourcePath -Blob $BlobName -Container $StorageContainerName -Context $StorageAccountContext -Force -ErrorAction Stop
106 | }
107 |
108 | # Generate the value for artifacts location SAS token if it is not provided in the parameter file
109 | $ArtifactsLocationSasToken = $OptionalParameters[$ArtifactsLocationSasTokenName]
110 | if ($ArtifactsLocationSasToken -eq $null) {
111 | # Create a SAS token for the storage container - this gives temporary read-only access to the container
112 | $ArtifactsLocationSasToken = New-AzureStorageContainerSASToken -Container $StorageContainerName -Context $StorageAccountContext -Permission r -ExpiryTime (Get-Date).AddHours(4)
113 | $ArtifactsLocationSasToken = ConvertTo-SecureString $ArtifactsLocationSasToken -AsPlainText -Force
114 | $OptionalParameters[$ArtifactsLocationSasTokenName] = $ArtifactsLocationSasToken
115 | }
116 | }
117 |
118 | # Create or update the resource group using the specified template file and template parameters file
119 | New-AzureRmResourceGroup -Name $ResourceGroupName -Location $ResourceGroupLocation -Verbose -Force -ErrorAction Stop
120 |
121 | $ErrorMessages = @()
122 | if ($ValidateOnly) {
123 | $ErrorMessages = Format-ValidationOutput (Test-AzureRmResourceGroupDeployment -ResourceGroupName $ResourceGroupName `
124 | -TemplateFile $TemplateFile `
125 | -TemplateParameterFile $TemplateParametersFile `
126 | @OptionalParameters `
127 | -Verbose)
128 | }
129 | else {
130 | New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $TemplateFile).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) `
131 | -ResourceGroupName $ResourceGroupName `
132 | -TemplateFile $TemplateFile `
133 | -TemplateParameterFile $TemplateParametersFile `
134 | @OptionalParameters `
135 | -Force -Verbose `
136 | -ErrorVariable ErrorMessages
137 | $ErrorMessages = $ErrorMessages | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") }
138 | }
139 | if ($ErrorMessages)
140 | {
141 | "", ("{0} returned the following errors:" -f ("Template deployment", "Validation")[[bool]$ValidateOnly]), @($ErrorMessages) | ForEach-Object { Write-Output $_ }
142 | }
--------------------------------------------------------------------------------
/azuredeploy.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "vmName": {
6 | "type": "string"
7 | },
8 | "vmSize": {
9 | "type": "string",
10 | "defaultValue": "Standard_DS13_v2",
11 | "allowedValues": [
12 | "Standard_D1",
13 | "Standard_D2",
14 | "Standard_D3",
15 | "Standard_D4",
16 | "Standard_DS13_v2"
17 | ],
18 | "metadata": {
19 | "description": "Size of VM"
20 | }
21 | },
22 | "adminUsername": {
23 | "type": "string"
24 | },
25 | "adminPassword": {
26 | "type": "securestring"
27 | },
28 | "sizeOf_E_Drive": {
29 | "type": "string",
30 | "defaultValue": "127",
31 | "metadata": {
32 | "description": "Size of E:/ drive in GB"
33 | }
34 | },
35 | "DiskCaching": {
36 | "type": "String",
37 | "defaultValue": "ReadOnly",
38 | "allowedValues": [
39 | "ReadOnly",
40 | "ReadWrite"
41 | ]
42 | },
43 | "IPAdress": {
44 | "defaultValue": "10.0.0.4",
45 | "type": "string"
46 | },
47 | "StorageType": {
48 | "type": "string",
49 | "defaultValue": "Premium_LRS",
50 | "allowedValues": [
51 | "Standard_LRS",
52 | "Premium_LRS"
53 | ]
54 | },
55 | "IPAddressesType": {
56 | "defaultValue": "Static",
57 | "type": "String",
58 | "allowedValues": [
59 | "Dynamic",
60 | "Static"
61 | ]
62 | }
63 | },
64 | "variables": {
65 | "virtualNetworkName": "[concat(parameters('vmName'),'_VNET')]",
66 | "networkInterfaceName": "[concat(parameters('vmName'),'_nic')]",
67 | "addressPrefix": "10.0.0.0/16",
68 | "vnetId": "[resourceId('ProdataARM','Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
69 | "subnetRef": "[concat(variables('vnetId'), '/subnets/', variables('subnetName'))]",
70 | "addressPrefix": "10.0.0.0/24",
71 | "storageAccountName": "prodataarmdisks494",
72 | "diagnosticsStorageAccountName": "prodataarmdiag702",
73 | "diagnosticsStorageAccountId": "\"[concat(\"Microsoft.Storage/storageAccounts/\",diagnosticsStorageAccountName)]\"",
74 | "diagnosticsStorageAccountType": "Standard_LRS",
75 | "publicIpAddressName": "[concat(parameters('vmName'),'_PublicIP')]",
76 | "subnetPrefix": "10.0.0.0/24",
77 | "subnetName": "default",
78 | "networkSecurityGroupName": "[concat(parameters('vmName'),'_NSG')]",
79 | "sqlConnectivityType": "Private",
80 | "sqlPortNumber": 1433,
81 | "sqlStorageDisksCount": 1,
82 | "sqlStorageWorkloadType": "DW",
83 | "sqlStorageDisksConfigurationType": "NEW",
84 | "sqlStorageStartingDeviceId": 2,
85 | "sqlStorageDeploymentToken": 96257,
86 | "sqlAutopatchingDayOfWeek": "Sunday",
87 | "sqlAutopatchingStartHour": 2,
88 | "sqlAutopatchingWindowDuration": "60",
89 | "rServicesEnabled": "false"
90 | },
91 | "resources": [
92 | {
93 | "name": "[parameters('vmName')]",
94 | "type": "Microsoft.Compute/virtualMachines",
95 | "apiVersion": "2016-03-30",
96 | "location": "[resourceGroup().location]",
97 | "dependsOn": [
98 | "[concat('Microsoft.Network/networkInterfaces/', variables('networkInterfaceName'))]",
99 | "[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
100 | "[concat('Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName'))]"
101 | ],
102 | "properties": {
103 | "osProfile": {
104 | "computerName": "[parameters('vmName')]",
105 | "adminUsername": "[parameters('adminUsername')]",
106 | "adminPassword": "[parameters('adminPassword')]",
107 | "windowsConfiguration": {
108 | "provisionVmAgent": "true"
109 | }
110 | },
111 | "hardwareProfile": {
112 | "vmSize": "[parameters('vmSize')]"
113 | },
114 | "storageProfile": {
115 | "imageReference": {
116 | "publisher": "MicrosoftSQLServer",
117 | "offer": "SQL2016SP1-WS2016",
118 | "sku": "SQLDEV",
119 | "version": "latest"
120 | },
121 | "osDisk": {
122 | "name": "[concat(parameters('vmName'), '_C_Drive')]",
123 | "createOption": "fromImage",
124 | "vhd": {
125 | "uri": "[concat(concat(reference(resourceId('ProdataARM', 'Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2015-06-15').primaryEndpoints['blob'], 'vhds/'), parameters('vmName'), '_C_drive', '.vhd')]"
126 | }
127 | },
128 | "dataDisks": [
129 | {
130 | "name": "[concat(parameters('vmName'), '_E_Drive')]",
131 | "createOption": "empty",
132 | "lun": 0,
133 | "diskSizeGB": "[parameters('sizeOf_E_Drive')]",
134 | "caching": "[parameters('DiskCaching')]",
135 | "vhd": {
136 | "uri": "[concat(concat(reference(resourceId('ProdataARM', 'Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2015-06-15').primaryEndpoints['blob'], 'vhds/'), parameters('vmName'), '_E_drive', '.vhd')]"
137 | }
138 | }
139 | ]
140 | },
141 | "networkProfile": {
142 | "networkInterfaces": [
143 | {
144 | "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
145 | }
146 | ]
147 | },
148 | "diagnosticsProfile": {
149 | "bootDiagnostics": {
150 | "enabled": true,
151 | "storageUri": "[reference(resourceId('ProdataARM', 'Microsoft.Storage/storageAccounts', variables('diagnosticsStorageAccountName')), '2015-06-15').primaryEndpoints['blob']]"
152 | }
153 | }
154 | }
155 | },
156 | {
157 | "apiVersion": "2015-06-15",
158 | "type": "Microsoft.Compute/virtualMachines/extensions",
159 | "name": "[concat(parameters('vmName'), '/SqlIaasExtension')]",
160 | "location": "[resourceGroup().location]",
161 | "dependsOn": [
162 | "[concat('Microsoft.Compute/virtualMachines/', parameters('vmName'))]",
163 | "[concat('Microsoft.Compute/virtualMachines/', parameters('vmName'))]"
164 | ],
165 | "properties": {
166 | "type": "SqlIaaSAgent",
167 | "publisher": "Microsoft.SqlServer.Management",
168 | "typeHandlerVersion": "1.2",
169 | "autoUpgradeMinorVersion": "true",
170 | "settings": {
171 | "AutoTelemetrySettings": {
172 | "Region": "[resourceGroup().location]"
173 | },
174 | "AutoPatchingSettings": {
175 | "PatchCategory": "WindowsMandatoryUpdates",
176 | "Enable": true,
177 | "DayOfWeek": "[variables('sqlAutopatchingDayOfWeek')]",
178 | "MaintenanceWindowStartingHour": "[variables('sqlAutopatchingStartHour')]",
179 | "MaintenanceWindowDuration": "[variables('sqlAutopatchingWindowDuration')]"
180 | },
181 | "KeyVaultCredentialSettings": {
182 | "Enable": false,
183 | "CredentialName": ""
184 | },
185 | "ServerConfigurationsManagementSettings": {
186 | "SQLConnectivityUpdateSettings": {
187 | "ConnectivityType": "[variables('sqlConnectivityType')]",
188 | "Port": "[variables('sqlPortNumber')]"
189 | },
190 | "SQLWorkloadTypeUpdateSettings": {
191 | "SQLWorkloadType": "[variables('sqlStorageWorkloadType')]"
192 | },
193 | "SQLStorageUpdateSettings": {
194 | "DiskCount": "[variables('sqlStorageDisksCount')]",
195 | "NumberOfColumns": "[variables('sqlStorageDisksCount')]",
196 | "StartingDeviceID": "[variables('sqlStorageStartingDeviceId')]",
197 | "DiskConfigurationType": "[variables('sqlStorageDisksConfigurationType')]"
198 | },
199 | "AdditionalFeaturesServerConfigurations": {
200 | "IsRServicesEnabled": "[variables('rServicesEnabled')]"
201 | }
202 | }
203 | },
204 | "protectedSettings": {}
205 | }
206 | },
207 | {
208 | "name": "[variables('storageAccountName')]",
209 | "type": "Microsoft.Storage/storageAccounts",
210 | "apiVersion": "2015-06-15",
211 | "location": "[resourceGroup().location]",
212 | "properties": {
213 | "accountType": "[parameters('storageType')]"
214 | }
215 | },
216 | {
217 | "name": "[variables('diagnosticsStorageAccountName')]",
218 | "type": "Microsoft.Storage/storageAccounts",
219 | "apiVersion": "2015-06-15",
220 | "location": "[resourceGroup().location]",
221 | "properties": {
222 | "accountType": "[variables('diagnosticsStorageAccountType')]"
223 | }
224 | },
225 | {
226 | "name": "[variables('virtualNetworkName')]",
227 | "type": "Microsoft.Network/virtualNetworks",
228 | "apiVersion": "2016-09-01",
229 | "location": "[resourceGroup().location]",
230 | "properties": {
231 | "addressSpace": {
232 | "addressPrefixes": [
233 | "[variables('addressPrefix')]"
234 | ]
235 | },
236 | "subnets": [
237 | {
238 | "name": "[variables('subnetName')]",
239 | "properties": {
240 | "addressPrefix": "[variables('subnetPrefix')]"
241 | }
242 | }
243 | ]
244 | }
245 | },
246 | {
247 | "name": "[variables('networkInterfaceName')]",
248 | "type": "Microsoft.Network/networkInterfaces",
249 | "apiVersion": "2016-09-01",
250 | "location": "[resourceGroup().location]",
251 | "dependsOn": [
252 | "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
253 | "[concat('Microsoft.Network/publicIpAddresses/', variables('publicIpAddressName'))]",
254 | "[concat('Microsoft.Network/networkSecurityGroups/', variables('networkSecurityGroupName'))]"
255 | ],
256 | "properties": {
257 | "ipConfigurations": [
258 | {
259 | "name": "ipconfig1",
260 | "properties": {
261 | "subnet": {
262 | "id": "[variables('subnetRef')]"
263 | },
264 | "privateIPAddress": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('IPAdress'))]",
265 | "privateIPAllocationMethod": "Dynamic",
266 | "publicIpAddress": {
267 | "id": "[resourceId('ProdataARM','Microsoft.Network/publicIpAddresses', variables('publicIpAddressName'))]"
268 | }
269 | }
270 | }
271 | ],
272 | "networkSecurityGroup": {
273 | "id": "[resourceId('ProdataARM', 'Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
274 | }
275 | }
276 | },
277 | {
278 | "name": "[variables('publicIpAddressName')]",
279 | "type": "Microsoft.Network/publicIpAddresses",
280 | "apiVersion": "2016-09-01",
281 | "location": "[resourceGroup().location]",
282 | "properties": {
283 | "publicIpAllocationMethod": "[parameters('IPAddressesType')]"
284 | }
285 | },
286 | {
287 | "name": "[variables('networkSecurityGroupName')]",
288 | "type": "Microsoft.Network/networkSecurityGroups",
289 | "apiVersion": "2016-09-01",
290 | "location": "[resourceGroup().location]",
291 | "properties": {
292 | "securityRules": [
293 | {
294 | "name": "default-allow-rdp",
295 | "properties": {
296 | "priority": 1000,
297 | "sourceAddressPrefix": "*",
298 | "protocol": "TCP",
299 | "destinationPortRange": "3389",
300 | "access": "Allow",
301 | "direction": "Inbound",
302 | "sourcePortRange": "*",
303 | "destinationAddressPrefix": "*"
304 | }
305 | }
306 | ]
307 | }
308 | }
309 | ],
310 | "outputs": {
311 | "adminUsername": {
312 | "type": "string",
313 | "value": "[parameters('adminUsername')]"
314 | }
315 | }
316 | }
--------------------------------------------------------------------------------