Azure Automation DSC Config example

There’s a couple of ways to do DSC on Azure, you can deploy a template and use the DSC extension resource to deploy DSC configuration to your VM (simple for quick simple deployments), or you can leverage Azure Automation as a DSC Pull server (subject of this blog), where you store all your DSC configuration scripts, MOF files and manage all your DSC nodes, to see drift, compliance etc.

This blog post discusses my github repo, which:

  • Deploys an Azure VM
  • Deploys a vNet into a separate Resource Group (Cross Resource Group Deployment), a resource group used for shared resources
  • Leverages the Custom Script extension which runs a script as the local computer account at the time of deployment. This script copies a script from the artifcats location to the local C:\ drive to be used as a user logon script. The DSC sets up a scheduled task to call the script at the time of any user logon.
  • This blog post:
    • leverages the DSC extension only to register the VM with the Azure Automation pull server in order for DSC to run the configuration on the VM
  • My other blog post
    • leverages the DSC extension to run the configuration on the VM. The JSON template also feeds parameter values into a DSC configuration script via the DSC extension

Note, this blog post focuses on my Github repo https://github.com/marckean/Azure-DSC-Automation where I have full repo of a working demo of deploying a VM to Azure using Infrastructure as Code along with further configuration with the Windows OS itself using Configuration as Code, my favourite is PowerShell DSC (Desired State Configuration).

Before moving on, you should be somewhat familiar with all the GIT, VS Code, Fork, Branch, Push, Commit, Clone terms as well as have all the tools – to get started setting up all the tooling to start using VS Code & GIT, my other blog post walks you through setting up all the tooling you need. Do this and have a play, it’s seriously addictive.

Back to this, as for my GitHub repo, you should:

  • Fork my repo to your own GitHub account from GitHub’s website.2018-06-28_2125
  • Using Github desktop, clone your newly forked repository to your local computer.

2018-06-28_2045

  • Then open the repository in VS Code Open Folder

For this demo, as this is focused Azure Automation DSC, you need to first add an Azure Automation account if you don’t already have one.

2018-06-28_1959

From the Azure Automation account, add a configuration, this is a .ps1 file which you need to upload – available at the very bottom of this page.

2018-06-28_2001

The .ps1 file you want to add is the script is further below, make sure you copy & paste the contents to a new file on your desktop and save this file specifically as main.ps1 before uploading in the Azure portal, otherwise the upload will fail.

2018-06-28_2006

Once this is uploaded, you need to compile this DSC configuration which creates a DSC node configuration (MOF file).

This is the same as running:

Main -nodeName $env:COMPUTERNAME -VNCKey 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX' -OutputPath "$env:USERPROFILE\Desktop"

2018-06-28_2007

It takes a few minutes to compile.

Things to keep in mind, most of this of this DSC Configuration file will require Source Files to be accessed from a blob storage account.

Source Files – artifacts

Source Files / Build Files / Artifacts used in the process of DSC configuration has always been a challenge. Where to place them centrally so they’re accessible for all deployments. Source files can be other scripts, files, or software packages to install on your machines.

The best place I have found to store source files is in a good old Azure Storage account container e.g.

https://msmarcsg.blob.core.windows.net/deployment

You give the storage account container anonymous read access.

2018-06-28_2024

You’re probably thinking no way! This is way too in-secure!! Not really, you encrypt all files other than the normal .exe & .msi files, you encrypt all your sensitive files using Rijndael encryption (pronounced rain-dahl), it is the algorithm that has been selected by the U.S. National Institute of Standards and Technology (NIST) as the candidate for the Advanced Encryption Standard (AES) – see.

Encryption is easy and done locally on your computer by following my other blog post Storing Files safely & securely in Publicly Accessible Storage.

As per this other blog, you normally would:

  1. Create a certificate used to encrypt the files, this generates a Private Key on your computer
  2. Export the Private Key as a .PFX file to your local computer – ready to add to Azure’s Key Vault
  3. Encrypt the files in a local (Source Files) designated folder on your computer as per my blog
  4. Upload these encrypted files to an Azure Blob storage container using Azure Storage Explorer.

However, for this blog post demonstration for DSC, I will provide you the certificate you need. As for the source files, I will provide demo ones… Below is what my folder structure looks like in order for this demo DSC configuration to work. As you can see, some of the files have a .encrypted extension, to indicate the files are encrypted.

2018-06-28_2035

In a normal world, you would want to add your own source files if you wanted to do this properly, so simply change this line in the below script to suit your storage account container.

$PublicStorageSourceContainer = 'https://msmarcsg.blob.core.windows.net/deployment'

Encryption Certificate Azure Key Vault

In a real world, you would create your own certificate to protect your source files – however for this demo, use this certificate. Password is Passw0rd.

You can run DSC configurations locally on test machines to make sure DSC runs correctly, you can see it apply in real-time. This is highly beneficial to speed up testing for errors instead of waiting each time for a full deployment. If you want to experiment and run it locally, you would need to add this same certificate to the local machine certificate store on your test computer…. Double click on the certificate and follow your nose.

2018-06-28_2139.png

For this demonstration, you upload this certificate (you just downloaded) to Azure’s Key Vault.

2018-06-28_2137

You need to then click on the newly imported certificate in Azure Key Vault, then copy the Secret Identifier to the clipboard of your computer. You will use this imediately below in the JSON template.

2018-06-28_2140

To allow Azure services to be able to access Azure Key Vault, you’ll need to open it up to allow access.

Logon to https://resources.azure.com same as your Azure logon. Navigate through the levels to where your Key Vault is located…. Subscriptions > {Your Subscription} > resourceGroups > {Your Resource Group} > providers > vaults……

Select your Key Vault, then on the right select both ReadWrite & Edit.

2018-06-29_0721

At the very bottom, change the 3 items to say ‘true‘, then press the PUT button at the top to apply the settings.

2018-06-29_0722

Changes to the JSON Template

Make sure you have the local copy of the GitHub repo folder open in VS Code….

2018-06-28_2143

Select the JSON template, in VS Code you need to run through all the parameters at the top and in the parameters file, change the settings as you see fit to suite your environment. For instance the Azure Automation parameters.

You also need to change specifically the Secret Identifier as per the step above.

2018-06-28_2039

Once you’re happy everything looks good | Save, commit the file locally, then sync to your GitHub repo.

Setup a Build definition in VSTS

You need to use VSTS to do the deployment of your GitHub repo JSON template to Azure. For the Build Definition in VSTS, use the GitHub repo as the source, this will be the same GitHub repo you forked from me, your own GitHub account.

2018-06-28_2110

You want to start with an empty pipeline:

2018-06-28_2118

Add both Azure Resource Group DeploymentAzure PowerShell tasks and configure the obvious stuff along with the not so obvious stuff as per further below.

2018-07-24_1652.png

Configure Azure Resource Group Deployment as per:

Template:

$(Build.SourcesDirectory)/BlankResourceGroup.json

Configure Azure PowerShell as per:

Script Path:

$(Build.SourcesDirectory)/Deploy-AzureResourceGroup.ps1

Script Arguments:

-ResourceGroupName 'RG-Name-ChangeThis' -ResourceGroupLocation 'australiaeast' -TemplateFile '$(Build.SourcesDirectory)\WindowsVirtualMachine.json' -TemplateParametersFile '$(Build.SourcesDirectory)\WindowsVirtualMachine.parameters.json' -UploadArtifacts -ArtifactStagingDirectory '$(Build.SourcesDirectory)'

That’s it, go and hit build.


configuration Main
{
param
(
[string]$JukeboxID = "localhost",
[string]$nodeName = $env:COMPUTERNAME,
[string]$VNCKey
)
#Import-DscResource -Name 'xRemoteFile' -ModuleName '.\xPSDesiredStateConfiguration'
<# xPSDesiredStateConfiguration containes….
xDscWebService, xWindowsProcess, xService, xPackage
xArchive, xRemoteFile, xPSEndpoint, xWindowsOptionalFeature
#>
$SourceFiles = "$env:SystemDrive\SourceFiles"
$PublicStorageSourceContainer = 'https://msmarcsg.blob.core.windows.net/deployment'
Node $env:COMPUTERNAME
{
File SourceFiles
{
DestinationPath = $SourceFiles
Ensure = 'Present'
Type = 'Directory'
}
File PHPFiles
{
SourcePath = "$SourceFiles\PHP\PHP-7.0.13"
DestinationPath = "$env:SystemDrive\PHP\7.0.13"
Ensure = 'Present'
Type = 'Directory'
Recurse = $true
DependsOn = "[Script]UnEncryptSourceFiles"
}
File WinCache
{
SourcePath = "$SourceFiles\PHP\WinCache 2.0.0.8\php_wincache.dll"
DestinationPath = "$env:SystemDrive\PHP\7.0.13\ext"
Ensure = 'Present'
Type = 'File'
DependsOn = "[File]PHPFiles"
}
################################################################################
################## Packages, Software Installation
################################################################################
#region Packages
Package InstallVNCServer
{
Ensure = "Present"
Path = "$SourceFiles\RealVNC\VNC-Server-5.3.2-Windows-en-64bit.msi"
Name = "VNC Server 5.3.2"
ProductId = "{BD3BF59A-3CD6-49B3-A166-E57BF55FF959}"
#DependsOn = "[Script]UnEncryptSourceFiles"
#Arguments = "ADDLOCAL=ALL"
DependsOn = "[Script]UnEncryptSourceFiles"
}
Package PHPManagerForIIS
{
Ensure = "Present"
Path = "$SourceFiles\PHP\PHP Manager 1.4.0\PHPManagerForIIS-1.4.0-x64.msi"
ProductId = "{E851486F-1FE2-44F0-85ED-F969088A68EE}"
Name = "PHP Manager 1.4 for IIS 10"
DependsOn = @("[Script]UnEncryptSourceFiles","[WindowsFeature]WAS-NET-Environment")
}
Package InstallAzCopy
{
Ensure = "Present"
Path = "$SourceFiles\MicrosoftAzureStorageTools.msi"
Name = "Microsoft Azure Storage Tools – v6.1.0"
ProductId = "{1D24B7AC-AFB4-44D4-928B-5CB14ABF4839}"
#Arguments = "ADDLOCAL=ALL"
DependsOn = "[Script]DownloadAzCopy"
}
#endregion
################################################################################
################## Windows Features
################################################################################
#region Windows Features
foreach ($Feature in @("Web-Server","Web-Common-Http","Web-Static-Content", `
"Web-Default-Doc","Web-Dir-Browsing","Web-Http-Errors",`
"Web-Health","Web-Http-Logging","Web-Log-Libraries",`
"Web-Request-Monitor","Web-Security","Web-Filtering",`
"Web-Stat-Compression","Web-Http-Redirect","Web-Mgmt-Tools",`
"WAS","WAS-Process-Model","WAS-NET-Environment","WAS-Config-APIs","Web-CGI"))
{
WindowsFeature $Feature
{
Name = $Feature
Ensure = "Present"
}
}
#endregion
################################################################################
################## Scripts
################################################################################
#region Scripts
Script DownloadAzCopy
{
TestScript = { # the TestScript block runs first. If the TestScript block returns $false, the SetScript block will run
Test-Path "$using:SourceFiles\MicrosoftAzureStorageTools.msi"
}
SetScript = {
$source = "$using:PublicStorageSourceContainer/AzCopy/MicrosoftAzureStorageTools.msi"
$dest = "$using:SourceFiles\MicrosoftAzureStorageTools.msi"
Invoke-WebRequest $source OutFile $dest
}
GetScript = { # should return a hashtable representing the state of the current node
$result = Test-Path "$using:SourceFiles\MicrosoftAzureStorageTools.msi"
@{
"Downloaded" = $result
}
}
DependsOn = "[File]SourceFiles"
}
Script CopyEncryptedSourceFiles
{
TestScript = { # the TestScript block runs first. If the TestScript block returns $false, the SetScript block will run
Test-Path "$using:SourceFiles\Scripts"
}
SetScript = {
$azPath = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\AzCopy"
Remove-Item Path $env:USERPROFILE\AppData\Local\Microsoft\Azure\AzCopy\*.* Force ErrorAction SilentlyContinue
$prog ="${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\AzCopy\AzCopy.exe"
$AzsrcUri = $using:PublicStorageSourceContainer
$TargetDir = "$using:SourceFiles"
$params=@("/source:$AzsrcUri /Dest:$TargetDir /s /y")
Start-Process $prog $params Wait
}
GetScript = { # should return a hashtable representing the state of the current node
$result = Test-Path "$using:SourceFiles\Scripts"
@{
"Downloaded" = $result
}
}
DependsOn = "[Package]InstallAzCopy"
}
# Un-Encrypt Scripts
Script UnEncryptSourceFiles
{
TestScript = { # the TestScript block runs first. If the TestScript block returns $false, the SetScript block will run
if (!(Get-ChildItem "$using:SourceFiles" Recurse Filter *.encrypted)) {return $True}
else {return $False}
}
SetScript = {
# change the following two secret phrases
$salt = "Marc01"
$init = "Marc6491649137"
# supply a strong password
$CertThumbprint = (Get-ChildItem cert:\LocalMachine\My |
Where-Object FilterScript {$_.PrivateKey -and ($_.EnhancedKeyUsageList.FriendlyName -eq 'Document Encryption') -and ($_.Issuer -notmatch 'microsoft.com')}).Thumbprint
$password = $CertThumbprint
function Decrypt-File([string]$encryptedFile, [string]$decryptedFile)
{
if($decryptedFile -eq $null -or $decryptedFile -eq "")
{
$decryptedFile = $encryptedFile
}
$rijndaelCSP = New-Object System.Security.Cryptography.RijndaelManaged
$pass = [System.Text.Encoding]::UTF8.GetBytes($password)
$salt = [System.Text.Encoding]::UTF8.GetBytes($salt)
$rijndaelCSP.Key = (New-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32) #256/8
$rijndaelCSP.IV = (New-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]
$decryptor = $rijndaelCSP.CreateDecryptor()
$inputFileStream = New-Object System.IO.FileStream($encryptedFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
$decryptStream = New-Object Security.Cryptography.CryptoStream $inputFileStream, $decryptor, "Read"
[int]$dataLen = $inputFileStream.Length
[byte[]]$inputFileData = New-Object byte[] $dataLen
[int]$decryptLength = $decryptStream.Read($inputFileData, 0, $dataLen)
$decryptStream.Close()
$inputFileStream.Close()
$outputFileStream = New-Object System.IO.FileStream($decryptedFile, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
$outputFileStream.Write($inputFileData, 0, $decryptLength)
$outputFileStream.Close()
$rijndaelCSP.Clear()
}
# Decrypt all files except .exe .msi
$RawFilesLocation = "$using:SourceFiles"
$RawFiles = Get-ChildItem $RawFilesLocation Recurse | ? {$_.Attributes -notlike '*Directory*' -and $_.Extension -like '*encrypted'}
foreach($RawFile in $RawFiles){
DecryptFile $RawFile.FullName ($RawFile.FullName -replace "\.encrypted")
Remove-Item $RawFile.FullName Force
}
}
GetScript = { # should return a hashtable representing the state of the current node
if (!(Get-ChildItem "$using:SourceFiles" Recurse Filter *.encrypted)) {$result = $True}
else {$result = $False}
@{
"DecryptedFiles" = $result
}
}
DependsOn = "[Script]CopyEncryptedSourceFiles"
}
# Disable Password Complexity
Script DisablePasswordComplexity
{
TestScript = { # the TestScript block runs first. If the TestScript block returns $false, the SetScript block will run
$null = secedit /export /cfg $env:USERPROFILE\secpol.cfg
$null = (Get-Content $env:USERPROFILE\secpol.cfg) | ? {$_ -match 'PasswordComplexity.=.(.)'}
$null = Remove-Item force $env:USERPROFILE\secpol.cfg confirm:$false
# make sure PasswordComplexity is set to '0'
$Matches[1] -eq '0'
}
SetScript = {
# Disable Password Complexity
secedit /export /cfg $env:USERPROFILE\secpol.cfg
(gc $env:USERPROFILE\secpol.cfg).replace("PasswordComplexity = 1", "PasswordComplexity = 0") | Out-File $env:USERPROFILE\secpol.cfg
secedit /configure /db c:\windows\security\local.sdb /cfg $env:USERPROFILE\secpol.cfg /areas SECURITYPOLICY
Remove-Item force $env:USERPROFILE\secpol.cfg confirm:$false
}
GetScript = { # should return a hashtable representing the state of the current node
$null = secedit /export /cfg $env:USERPROFILE\secpol.cfg
$null = (Get-Content $env:USERPROFILE\secpol.cfg) | ? {$_ -match 'PasswordComplexity.=.(.)'}
$null = Remove-Item force $env:USERPROFILE\secpol.cfg confirm:$false
@{
"PasswordComplexity" = $Matches[1]
}
}
}
# Configure VNC Server
Script ConfigureVNCServer
{
TestScript = { # the TestScript block runs first. If the TestScript block returns $false, the SetScript block will run
if ((Get-ItemProperty Path 'HKLM:\Software\RealVNC\vncserver' ErrorAction SilentlyContinue).Password -eq '0db038a948f57c87f7e4608295c6ea23') {return $True}
else {return $False}
}
SetScript = {
$process = "$env:ProgramFiles\RealVNC\VNC Server\vnclicense.exe"
$arguments = "-add $using:VNCKey"
start-process $process ArgumentList $arguments Wait
New-ItemProperty Path 'HKLM:\Software\RealVNC\vncserver' Name 'Authentication' Value 'VncAuth' Force
New-ItemProperty Path 'HKLM:\Software\RealVNC\vncserver' Name 'CaptureMethod' Value '0' Force
New-ItemProperty Path 'HKLM:\Software\RealVNC\vncserver' Name 'EnableAutoUpdateChecks' Value '0' Force
New-ItemProperty Path 'HKLM:\Software\RealVNC\vncserver' Name 'Encryption' Value 'AlwaysOn' Force
New-ItemProperty Path 'HKLM:\Software\RealVNC\vncserver' Name 'HttpPort' Value '5190' Force
New-ItemProperty Path 'HKLM:\Software\RealVNC\vncserver' Name 'Password' Value 'facbcf50c3bf1c08' Force # Passw0rd
New-ItemProperty Path 'HKLM:\Software\RealVNC\vncserver' Name 'RfbPort' Value '5190' Force
New-ItemProperty Path 'HKLM:\Software\RealVNC\vncserver' Name 'UserPasswdVerifier' Value 'VncAuth' Force
Restart-Service Name vncserver Force
}
GetScript = { # should return a hashtable representing the state of the current node
$result = Test-Path Path "$env:ProgramFiles\RealVNC\VNC Server\vncserver.exe"
@{
"Installed" = $result
}
}
DependsOn = "[Package]InstallVNCServer"
}
# Map M Drive & Start Studio Scheduled Task
Script UserLogonScript
{
TestScript = { # the TestScript block runs first. If the TestScript block returns $false, the SetScript block will run
if (Get-ScheduledTask TaskName "UserLogonScript" ErrorAction SilentlyContinue) {return $True}
else {return $False}
}
SetScript = {
# M-Drive & StationPlaylist Studio ScheduledTask
# This will create a scheduled task which will run a UserLogonScript for any user that logs on changing the regional settings for the user to Australia.
$ShedService = New-Object comobject 'Schedule.Service'
$ShedService.Connect()
$Task = $ShedService.NewTask(0)
$Task.RegistrationInfo.Description = 'UserLogonScript'
$Task.Settings.Enabled = $true
$Task.Settings.AllowDemandStart = $true
$trigger = $task.triggers.Create(9)
$trigger.Enabled = $true
$action = $Task.Actions.Create(0)
$action.Path = 'PowerShell.exe'
$action.Arguments = '-ExecutionPolicy Unrestricted -File c:\UserLogonScript.ps1'
# $action.WorkingDirectory = ''
$taskFolder = $ShedService.GetFolder("\")
$taskFolder.RegisterTaskDefinition('UserLogonScript', $Task , 6, 'Users', $null, 4)
}
GetScript = { # should return a hashtable representing the state of the current node
if (Get-ScheduledTask TaskName "UserLogonScript" ErrorAction SilentlyContinue) {return $True}
else {$result = $False}
@{
"ScheduledTaskExists" = $result
}
}
}
# Set ACLs for PHP for IIS to process it appropriately
Script PHPACLs
{
TestScript = { # the TestScript block runs first. If the TestScript block returns $false, the SetScript block will run
$php_install = "$env:SystemDrive\php"
$PHPInstallACLs = ((Get-Acl $php_install).Access.IdentityReference)
$result = $false
$PHPInstallACLs | % {if($_.Value -eq 'IIS APPPOOL\DefaultAppPool'){$result = $True}}
return $result
}
SetScript = {
$php_install = "$env:SystemDrive\php"
$acl = get-acl $php_install
$ar = new-object system.security.accesscontrol.filesystemaccessrule("IIS AppPool\DefaultAppPool", "ReadAndExecute", "ContainerInherit, ObjectInherit", "None","Allow")
$acl.setaccessrule($ar)
$ar = new-object system.security.accesscontrol.filesystemaccessrule("Users", "ReadAndExecute", "ContainerInherit, ObjectInherit", "None","Allow")
$acl.setaccessrule($ar)
set-acl $php_install $acl
$php_log = "c:\phplog"
if ((Test-Path path $php_log) -ne $True) {
new-item type directory path $php_log}
$acl = get-acl $php_log
$ar = new-object system.security.accesscontrol.filesystemaccessrule("Users","Modify","Allow")
$acl.setaccessrule($ar)
$ar = new-object system.security.accesscontrol.filesystemaccessrule("IIS AppPool\DefaultAppPool", "Modify", "ContainerInherit, ObjectInherit", "None","Allow")
$acl.setaccessrule($ar)
set-acl $php_log $acl
$php_temp = "c:\phptemp"
if ((Test-Path path $php_temp) -ne $True) {
new-item type directory path $php_temp}
$acl = get-acl $php_temp
$ar = new-object system.security.accesscontrol.filesystemaccessrule("Users","Modify","Allow")
$acl.setaccessrule($ar)
$ar = new-object system.security.accesscontrol.filesystemaccessrule("IIS AppPool\DefaultAppPool", "Modify", "ContainerInherit, ObjectInherit", "None","Allow")
$acl.setaccessrule($ar)
set-acl $php_temp $acl
}
GetScript = { # should return a hashtable representing the state of the current node
$php_install = "$env:SystemDrive\php"
$PHPInstallACLs = ((Get-Acl $php_install).Access.IdentityReference)
$result = $false
$PHPInstallACLs | % {if($_.Value -eq 'IIS APPPOOL\DefaultAppPool'){$result = $True}}
@{
"PHPACLsConfigured" = $result
}
}
DependsOn = "[File]PHPFiles"
}
# Configure PHP for IIS
Script ConfigurePHP
{
TestScript = { # the TestScript block runs first. If the TestScript block returns $false, the SetScript block will run
$result = $true
if ( (Get-PSSnapin Name PHPManagerSnapin ErrorAction SilentlyContinue) -eq $null )
{
$result = $false
}
return $result
}
SetScript = {
$php_install = "$env:SystemDrive\php"
$php_version = '7.0.13'
$php_log = "$env:SystemDrive\phplog"
$php_temp = "$env:SystemDrive\phptemp"
$web_root = "$env:SystemDrive\inetpub\wwwroot"
$web_log = "$env:SystemDrive\wwwlogs"
Add-PsSnapin PHPManagerSnapin
Rename-Item Path "$php_install\$php_version\php.ini-production" NewName "$php_install\$php_version\php.ini" ErrorAction SilentlyContinue
New-PHPVersion ScriptProcessor "$php_install\$php_version\php-cgi.exe"
#Configure Home Office Settings
Set-PHPSetting name date.timezone value "Australia/Sydney"
Set-PHPSetting name upload_max_filesize value "10M"
Set-PHPSetting name fastcgi.impersonate Value '0'
Set-PHPSetting name max_execution_time Value '300'
#Move logging and temp space to e:
Set-PHPSetting name upload_tmp_dir value $php_temp
set-phpsetting name session.save_path value $php_temp
Set-PHPSetting name error_log value "$php_log\php-errors.log"
Set-PHPExtension name php_wincache.dll status enabled
if ((Test-Path path $web_root) -ne $True) {
new-item type directory path $web_root
$acl = get-acl $web_root
$ar = new-object system.security.accesscontrol.filesystemaccessrule("Users", "ReadAndExecute", "ContainerInherit, ObjectInherit", "None","Allow")
$acl.setaccessrule($ar)
set-acl $web_root $acl
}
if ((Test-Path path $web_log) -ne $True) {
new-item type directory path $web_log
$acl = get-acl $web_log
$ar = new-object system.security.accesscontrol.filesystemaccessrule("Users", "ReadAndExecute", "ContainerInherit, ObjectInherit", "None","Allow")
$acl.setaccessrule($ar)
set-acl $web_log $acl
}
}
GetScript = { # should return a hashtable representing the state of the current node
$result = $true
if ( (Get-PSSnapin Name PHPManagerSnapin ErrorAction SilentlyContinue) -eq $null )
{
$result = $false
}
@{
"PHPConfigured" = $result
}
}
DependsOn = "[Script]PHPACLs"
}
#endregion
################################################################################
################## Registry Stuff
################################################################################
#region Registry Stuff
Registry ExecutionPolicy
{
Ensure = 'Present'
Key = 'HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell\'
ValueName = 'ExecutionPolicy'
ValueData = 'Unrestricted'
ValueType = "String"
}
# Disable IE First Launch
Registry DisableFirstRunCustomize
{
Ensure = 'Present'
Key = 'HKLM:\Software\Policies\Microsoft\Internet Explorer\Main'
ValueName = 'DisableFirstRunCustomize'
ValueData = '1'
ValueType = "String"
}
# Disable IE First Launch – Admins
Registry InternetExplorerEnhancedSecurityConfigurationAdmins1
{
Ensure = 'Present'
Key = 'HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components'
ValueName = 'IsInstalled'
ValueData = '0'
ValueType = "DWORD"
}
Registry InternetExplorerEnhancedSecurityConfigurationAdmins2
{
Ensure = 'Present'
Key = 'HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}'
ValueName = 'IsInstalled'
ValueData = '0'
ValueType = "DWORD"
}
# Disable IE First Launch – Users
Registry InternetExplorerEnhancedSecurityConfigurationUsers1
{
Ensure = 'Present'
Key = 'HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}'
ValueName = 'IsInstalled'
ValueData = '0'
ValueType = "DWORD"
}
#endregion
}
}

https://gist.github.com/marckean/5a0df92e794fd3e1b2d11dfc5c9c6425

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s