module/AzureFunctions.ps1
function New-AzSystemData { <# .SYNOPSIS Generates system data for Azure Virtual Machines .PARAMETER RootPath Root path of the Stig Compliance Automation Repository. Initialize by running Initialize-StigRepo .PARAMETER ResourceGroupName Name of the ResourceGroup containing targeted Virtual Machines .PARAMETER IncludeLcmSettings Adds LocalConfigurationManager Settings to the System Data File for each Virtual Machine. .PARAMETER LcmSettings Hashtable of Local Configuration Manager Settings .EXAMPLE New-AzSystemData -RootPath "C:\StigRepo" -ResourceGroupName "My-Azure-ResourceGroup" #> [CmdletBinding()] param ( [Parameter()] [string] $RootPath = (Get-Location).Path, [Parameter()] [string] $ResourceGroupName, # [Parameter()] # [switch] # $IncludeFilePaths, [Parameter()] [switch] $IncludeLCMSettings, [Parameter()] [HashTable] $LcmSettings = @{ actionAfterReboot = "" agentId = "" allowModuleOverwrite = $True certificateID = "" configurationDownloadManagers = "" configurationID = "" configurationMode = "ApplyAndAutoCorrect" configurationModeFrequencyMins = "15" credential = "" debugMode = "" downloadManagerCustomData = "" downloadManagerName = "" lcmStateDetail = "" maximumDownloadSizeMB = "500" partialConfigurations = "" rebootNodeIfNeeded = $False refreshFrequencyMins = "30" refreshMode = "PUSH" reportManagers = "{}" resourceModuleManagers = "{}" signatureValidationPolicy = "" signatureValidations = "{}" statusRetentionTimeInDays = "10" } ) Write-Output "Starting Azure SystemData Creation" $IncludeFilePaths = $true $systemsPath = (Resolve-Path "$RootPath\Systems").Path $resourceGroups = New-Object System.Collections.ArrayList $virtualMachines = New-Object System.Collections.ArrayList if ("" -eq $ResourceGroupName) { Get-AzVM | ForEach-Object { $null = $virtualMachines.Add($_) } } else { Get-AzVM -ResourceGroupName $ResourceGroupName | ForEach-Object { $null = $virtualMachines.Add($_) } } $virtualMachines.ResourceGroupName | Get-Unique | Foreach-Object { $null = $resourceGroups.Add($_) } foreach ($resourceGroup in $ResourceGroups) { Write-Output "`t$ResourceGroup - Generating System Data" $jobs = New-Object System.Collections.ArrayList $rgFolder = (New-Item -ItemType Directory -Path "$SystemsPath\$resourceGroup" -Force).FullName $resourceGroupVMs = $virtualMachines | Where-Object ResourceGroupName -eq $resourceGroup #region VirtualMachine Jobs foreach ($virtualMachine in $resourceGroupVms) { Write-Output "`t`tStarting Job - $($virtualMachine.name)" $osVersion = $virtualMachine.StorageProfile.ImageReference.Sku $vmName = $virtualMachine.Name $job = Start-Job -ScriptBlock { $RootPath = $using:rootPath $resourceGroup = $using:resourceGroup $rgFolder = $using:rgFolder $osVersion = $using:osVersion $vmName = $using:vmName $LcmSettings = $using:LcmSettings $dataFilePath = New-Item "$rgFolder\$vmName.psd1" -Force $applicableStigs = New-Object System.Collections.ArrayList #region STIG Applicability if ($DomainControllers) { $osRole = 'DC' $null = $applicableStigs.add("DomainController") } else { $osRole = 'MS' $null = $applicableStigs.add("WindowsServer") } $null = $applicableStigs.add("InternetExplorer") $null = $applicableStigs.add("WindowsFirewall") $null = $applicableStigs.add("WindowsDefender") $null = $applicableStigs.add("DotnetFramework") #endRegion #region Get STIG Files if ($IncludeFilePaths) { switch -Wildcard ($applicableStigs) { "WindowsServer*" { $osStigFiles = @{ orgSettings = Get-StigFiles -Rootpath $RootPath -StigType "WindowsServer" -Version $osVersion -FileType "OrgSettings" -NodeName $vmName xccdfPath = Get-StigFiles -Rootpath $RootPath -StigType "WindowsServer" -Version $osVersion -FileType "Xccdf" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $RootPath -StigType "WindowsServer" -Version $osVersion -FileType "ManualChecks" -NodeName $vmName } } "DotNetFramework" { $dotNetStigFiles = @{ orgsettings = Get-StigFiles -Rootpath $Rootpath -StigType "DotNetFramework" -Version 4 -FileType "OrgSettings" -NodeName $vmName xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "DotNetFramework" -Version 4 -FileType "Xccdf" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "DotNetFramework" -Version 4 -FileType "ManualChecks" -NodeName $vmName } } "InternetExplorer" { $ieStigFiles = @{ xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "InternetExplorer" -Version 11 -FileType "Xccdf" -NodeName $vmName orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "InternetExplorer" -Version 11 -FileType "OrgSettings" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "InternetExplorer" -Version 11 -FileType "ManualChecks" -NodeName $vmName } } "WindowsClient" { $Win10StigFiles = @{ orgSettings = Get-StigFiles -Rootpath $RootPath -StigType "WindowsClient" -Version $osVersion -FileType "OrgSettings" -NodeName $vmName xccdfPath = Get-StigFiles -Rootpath $RootPath -StigType "WindowsClient" -Version $osVersion -FileType "Xccdf" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $RootPath -StigType "WindowsClient" -Version $osVersion -FileType "ManualChecks" -NodeName $vmName } } "WindowsDefender" { $WinDefenderStigFiles = @{ orgSettings = Get-StigFiles -Rootpath $RootPath -StigType "WindowsDefender" -FileType "OrgSettings" -NodeName $vmName xccdfPath = Get-StigFiles -Rootpath $RootPath -StigType "WindowsDefender" -FileType "Xccdf" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $RootPath -StigType "WindowsDefender" -FileType "ManualChecks" -NodeName $vmName } } "WindowsFirewall" { $WinFirewallStigFiles = @{ orgSettings = Get-StigFiles -Rootpath $RootPath -StigType "WindowsFirewall" -FileType "OrgSettings" -NodeName $vmName xccdfPath = Get-StigFiles -Rootpath $RootPath -StigType "WindowsFirewall" -FileType "Xccdf" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $RootPath -StigType "WindowsFirewall" -FileType "ManualChecks" -NodeName $vmName } } "WindowsDnsServer" { $WindowsDnsStigFiles = @{ orgSettings = Get-StigFiles -Rootpath $RootPath -StigType "WindowsDnsServer" -FileType "OrgSettings" -NodeName $vmName xccdfPath = Get-StigFiles -Rootpath $RootPath -StigType "WindowsDnsServer" -FileType "Xccdf" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $RootPath -StigType "WindowsDnsServer" -FileType "ManualChecks" -NodeName $vmName } } "Office2016" { $word2016xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_Word" -Version 16 -FileType "Xccdf" -NodeName $vmName $word2016orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_Word" -Version 16 -FileType "OrgSettings" -NodeName $vmName $word2016manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_Word" -Version 16 -FileType "ManualChecks" -NodeName $vmName $powerpoint2016xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_PowerPoint" -Version 16 -FileType "Xccdf" -NodeName $vmName $powerpoint2016orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_PowerPoint" -Version 16 -FileType "OrgSettings" -NodeName $vmName $powerpoint2016manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_PowerPoint" -Version 16 -FileType "ManualChecks" -NodeName $vmName $outlook2016xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_Outlook" -Version 16 -FileType "Xccdf" -NodeName $vmName $outlook2016orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_Outlook" -Version 16 -FileType "OrgSettings" -NodeName $vmName $outlook2016manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_Outlook" -Version 16 -FileType "ManualChecks" -NodeName $vmName $excel2016xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_Excel" -Version 16 -FileType "Xccdf" -NodeName $vmName $excel2016orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_Excel" -Version 16 -FileType "OrgSettings" -NodeName $vmName $excel2016manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Office2016_Excel" -Version 16 -FileType "ManualChecks" -NodeName $vmName } "Office2013" { $word2013xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_word" -Version 15 -FileType "Xccdf" -NodeName $vmName $word2013orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_word" -Version 15 -FileType "OrgSettings" -NodeName $vmName $word2013manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_word" -Version 15 -FileType "ManualChecks" -NodeName $vmName $powerpoint2013xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_powerpoint" -Version 15 -FileType "Xccdf" -NodeName $vmName $powerpoint2013orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_powerpoint" -Version 15 -FileType "OrgSettings" -NodeName $vmName $powerpoint2013manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_powerpoint" -Version 15 -FileType "ManualChecks" -NodeName $vmName $outlook2013xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_outlook" -Version 15 -FileType "Xccdf" -NodeName $vmName $outlook2013orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_outlook" -Version 15 -FileType "OrgSettings" -NodeName $vmName $outlook2013manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_outlook" -Version 15 -FileType "ManualChecks" -NodeName $vmName $excel2013xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_excel" -Version 15 -FileType "Xccdf" -NodeName $vmName $excel2013orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_excel" -Version 15 -FileType "OrgSettings" -NodeName $vmName $excel2013manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Office2013_excel" -Version 15 -FileType "ManualChecks" -NodeName $vmName } "SQLServerInstance" { $version = "2016" $sqlInstanceStigFiles = @{ xccdfPath = Get-StigFiles -Rootpath $Rootpath -Version $Version -StigType "SqlServerInstance" -FileType "Xccdf" -NodeName $vmName orgSettings = Get-StigFiles -Rootpath $Rootpath -Version $Version -StigType "SqlServerInstance" -FileType "OrgSettings" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -Version $Version -StigType "SqlServerInstance" -FileType "ManualChecks" -NodeName $vmName } } "SqlServerDatabase" { $sqlDatabaseStigFiles = @{ xccdfPath = Get-StigFiles -Rootpath $Rootpath -Version $Version -StigType "SqlServerDataBase" -FileType "Xccdf" -NodeName $vmName orgSettings = Get-StigFiles -Rootpath $Rootpath -Version $Version -StigType "SqlServerDataBase" -FileType "OrgSettings" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -Version $Version -StigType "SqlServerDataBase" -FileType "ManualChecks" -NodeName $vmName } } "WebSite*" { $iisVersion = Invoke-Command -ComputerName $vmName -Scriptblock { $iisData = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\InetStp" $localIisVersion = "$($iisData.MajorVersion).$($iisData.MinorVersion)" return $localiisVersion } $WebsiteStigFiles = @{ xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "WebSite" -Version $iisVersion -FileType "Xccdf" -NodeName $vmName orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "WebSite" -Version $iisVersion -FileType "OrgSettings" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "WebSite" -Version $iisVersion -FileType "ManualChecks" -NodeName $vmName } } "WebServer*" { [decimal]$iisVersion = Invoke-Command -ComputerName $vmName -Scriptblock { $iisData = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\InetStp" $localIisVersion = "$($iisData.MajorVersion).$($iisData.MinorVersion)" return $localiisVersion } $webServerStigFiles = @{ xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "WebServer" -Version $iisVersion -FileType "Xccdf" -NodeName $vmName orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "WebServer" -Version $iisVersion -FileType "OrgSettings" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "WebServer" -Version $iisVersion -FileType "ManualChecks" -NodeName $vmName } } "McAfee" { $mcafeeStigFiles = @{ xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "McAfee" -FileType "Xccdf" -NodeName $vmName orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "McAfee" -FileType "OrgSettings" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "McAfee" -FileType "ManualChecks" -NodeName $vmName } } "FireFox" { $fireFoxStigFiles = @{ xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "FireFox" -FileType "Xccdf" -NodeName $vmName orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "FireFox" -FileType "OrgSettings" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "FireFox" -FileType "ManualChecks" -NodeName $vmName } } "Edge" { $edgeStigFiles = @{ xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Edge" -FileType "Xccdf" -NodeName $vmName orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "Edge" -FileType "OrgSettings" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Edge" -FileType "ManualChecks" -NodeName $vmName } } "Chrome" { $chromeStigFiles = @{ xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Chrome" -FileType "Xccdf" -NodeName $vmName orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "Chrome" -FileType "OrgSettings" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Chrome" -FileType "ManualChecks" -NodeName $vmName } } "Adobe" { $adobeStigFiles = @{ orgsettings = Get-StigFiles -Rootpath $Rootpath -StigType "Adobe" -FileType "OrgSettings" -NodeName $vmName xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "Adobe" -FileType "Xccdf" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "Adobe" -FileType "ManualChecks" -NodeName $vmName } } "OracleJRE" { $oracleStigFiles = @{ xccdfPath = Get-StigFiles -Rootpath $Rootpath -StigType "OracleJRE" -FileType "Xccdf" -NodeName $vmName orgSettings = Get-StigFiles -Rootpath $Rootpath -StigType "OracleJRE" -FileType "OrgSettings" -NodeName $vmName manualChecks = Get-StigFiles -Rootpath $Rootpath -StigType "OracleJRE" -FileType "ManualChecks" -NodeName $vmName } } } } #endRegion #region Build NodeData $configContent = New-Object System.Collections.ArrayList $null = $configContent.add("@{`n`tNodeName = `"$vmName`"") if ($null -ne $applicableSTIGs) { $null = $configContent.add("`n`n`tAppliedConfigurations =") $null = $configContent.add("`n`t@{") switch -Wildcard ($applicableSTIGs) { {$_ -like "WindowsServer*" -or $_ -like "DomainController"} { switch -Wildcard ($osVersion) { "*2012*" {$osVersion = "2012R2";break} "*2016*" {$osVersion = "2016";break} "*2019*" {$osVersion = "2019";break} } $null = $configContent.add("`n`n`t`tPowerSTIG_WindowsServer =") $null = $configContent.add("`n`t`t@{") $null = $configContent.add("`n`t`t`tOSRole = `"$osRole`"") $null = $configContent.add("`n`t`t`tOsVersion = `"$osVersion`"") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($osStigFiles.xccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($osStigFiles.orgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($osStigFiles.manualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`t`t}") } } "InternetExplorer" { $null = $configContent.add("`n`n`t`tPowerSTIG_InternetExplorer =") $null = $configContent.add("`n`t`t@{") $null = $configContent.add("`n`t`t`tBrowserVersion = `"11`"") $null = $configContent.add("`n`t`t`tSkipRule = `"V-46477`"") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($ieStigFiles.xccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($ieStigFiles.orgSettings)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`t`t}") } } "DotnetFrameWork" { $null = $configContent.add("`n`n`t`tPowerSTIG_DotNetFrameWork =") $null = $configContent.add("`n`t`t@{") $null = $configContent.add("`n`t`t`tFrameWorkVersion = `"4`"") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($dotNetStigFiles.xccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($dotNetStigFiles.orgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($dotNetStigFiles.manualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`t`t}") } } "WindowsClient" { $null = $configContent.add("`n`n`t`tPowerSTIG_WindowsClient =") $null = $configContent.add("`n`t`t@{") $null = $configContent.add("`n`t`t`tOSVersion = `"10`"") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($win10StigFiles.xccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($win10StigFiles.orgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($win10StigFiles.manualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } } "WindowsDefender" { $null = $configContent.add("`n`n`t`tPowerSTIG_WindowsDefender =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($winDefenderStigFiles.xccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($winDefenderStigFiles.orgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($winDefenderStigFiles.manualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } } "WindowsFirewall" { $null = $configContent.add("`n`n`t`tPowerSTIG_WindowsFirewall =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($winFirewallStigFiles.xccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($winFirewallStigFiles.orgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($winFirewallStigFiles.manualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } } "WindowsDnsServer" { $null = $configContent.add("`n`n`t`tPowerSTIG_WindowsDNSServer =") $null = $configContent.add("`n`t`t@{") $null = $configContent.add("`n`t`t`tOsVersion = `"$osVersion`"") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($WindowsDnsStigFiles.xccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($WindowsDnsStigFiles.orgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($WindowsDnsStigFiles.manualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`t`t}") } } "Office2016*" { $null = $configContent.add("`n`n`t`tPowerSTIG_Office2016_Excel =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$Excel2016xccdfPath`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$Excel2016OrgSettings`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$Excel2016ManualChecks`"") } $null = $configContent.add("`n`t`t}") $null = $configContent.add("`n`n`t`tPowerSTIG_Office2016_Outlook =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$Outlook2016xccdfPath`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$Outlook2016OrgSettings`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$Outlook2016ManualChecks`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } $null = $configContent.add("`n`n`t`tPowerSTIG_Office2016_PowerPoint =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$PowerPoint2016xccdfPath`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$PowerPoint2016OrgSettings`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$PowerPoint2016ManualChecks`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } $null = $configContent.add("`n`n`t`tPowerSTIG_Office2016_Word =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$Word2016xccdfPath`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$Word2016OrgSettings`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$Word2016ManualChecks`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } } "Office2013*" { $null = $configContent.add("`n`n`t`tPowerSTIG_Office2013_Excel =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$Excel2013xccdfPath`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$Excel2013OrgSettings`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$Excel2013ManualChecks`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } $null = $configContent.add("`n`n`t`tPowerSTIG_Office2013_Outlook =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$Outlook2013xccdfPath`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$Outlook2013OrgSettings`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$Outlook2013ManualChecks`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } $null = $configContent.add("`n`n`t`tPowerSTIG_Office2013_PowerPoint =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$PowerPoint2013xccdfPath`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$PowerPoint2013OrgSettings`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$PowerPoint2013ManualChecks`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } $null = $configContent.add("`n`n`t`tPowerSTIG_Office2013_Word =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$Word2013xccdfPath`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$Word2013OrgSettings`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$Word2013ManualChecks`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } } "Website*" { $websites = @(Invoke-Command -Computername $vmName -Scriptblock { Import-Module WebAdministration;Return (Get-Childitem "IIS:\Sites").name}) $appPools = @(Invoke-Command -Computername $vmName -Scriptblock { Import-Module WebAdministration;Return (Get-Childitem "IIS:\AppPools").name}) [string]$allWebSites = '' [string]$allAppPools = '' if ($websites.count -gt 1) { foreach ($site in $websites) { $allWebsites += "`"$site`"," } $websiteString = $allWebsites.TrimEnd(",") } else { $websiteString = "`"$websites`"" } if ($appPools.count -gt 1) { foreach ($appPool in $appPools) { $allAppPools += "`"$appPool`"," } $appPoolString = $allAppPools.TrimEnd(",") } else { $appPoolString = "`"$appPools`"" } $null = $configContent.add("`n`n`t`tPowerSTIG_WebSite =") $null = $configContent.add("`n`t`t@{") $null = $configContent.add("`n`t`t`tIISVersion = `"$IISVersion`"") $null = $configContent.add("`n`t`t`tWebsiteName = $websiteString") $null = $configContent.add("`n`t`t`tWebAppPool = $appPoolString") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($webSiteStigFiles.XccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($webSiteStigFiles.OrgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($webSiteStigFiles.ManualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`t`t}") } } "WebServer*" { $null = $configContent.add("`n`n`t`tPowerSTIG_WebServer =") $null = $configContent.add("`n`t`t@{") $null = $configContent.add("`n`t`t`tSkipRule = `"V-214429`"") $null = $configContent.add("`n`t`t`tIISVersion = `"$IISVersion`"") $null = $configContent.add("`n`t`t`tLogPath = `"C:\InetPub\Logs`"") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($webServerStigFiles.XccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($webServerStigFiles.OrgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($webServerStigFiles.ManualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } } "FireFox" { $null = $configContent.add("`n`n`t`tPowerSTIG_Firefox =") $null = $configContent.add("`n`t`t@{") $null = $configContent.add("`n`t`t`tInstallDirectory = `"C:\Program Files\Mozilla Firefox`"") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($firefoxStigFiles.XccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($firefoxStigFiles.OrgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($firefoxStigFiles.ManualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`t`t}") } } "Edge" { $null = $configContent.add("`n`n`t`tPowerSTIG_Edge =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($edgeStigFiles.xccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($edgeStigFiles.orgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($edgeStigFiles.manualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } } "Chrome" { $null = $configContent.add("`n`n`t`tPowerSTIG_Chrome =") $null = $configContent.add("`n`t`t@{") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($chromeStigFiles.xccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($chromeStigFiles.orgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($chromeStigFiles.manualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } } "Adobe" { $null = $configContent.add("`n`n`t`tPowerSTIG_Adobe =") $null = $configContent.add("`n`t`t@{") $null = $configContent.add("`n`t`t`tAdobeApp = `"AcrobatReader`"") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($adobeStigFiles.XccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($adobeStigFiles.OrgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($adobeStigFiles.ManualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`t`t}") } } "OracleJRE" { $null = $configContent.add("`n`n`t`tPowerSTIG_OracleJRE =") $null = $configContent.add("`n`t`t@{") $null = $configContent.add("`n`t`t`tConfigPath = `"$ConfigPath`"") $null = $configContent.add("`n`t`t`tPropertiesPath = `"$PropertiesPath`"") if ($IncludeFilePaths) { $null = $configContent.add("`n`t`t`txccdfPath = `"$($oracleStigFiles.XccdfPath)`"") $null = $configContent.add("`n`t`t`tOrgSettings = `"$($oracleStigFiles.OrgSettings)`"") $null = $configContent.add("`n`t`t`tManualChecks = `"$($oracleStigFiles.ManualChecks)`"") $null = $configContent.add("`n`t`t}") } else { $null = $configContent.add("`n`n`t`t}") } } } $null = $configContent.add("`n`t}") } if ($IncludeLcmSettings) { $null = $configContent.add("`n`n`tLocalConfigurationManager =") $null = $configContent.add("`n`t@{") foreach ($setting in $LcmSettings.Keys) { if (($Null -ne $LcmSettings.$setting) -and ("{}" -ne $lcmsettings.$setting) -and ("" -ne $LcmSettings.$setting)) { $null = $configContent.add("`n`t`t$($setting)") if ($setting.Length -lt 8) {$null = $configContent.add("`t`t`t`t`t`t`t= ")} elseif ($setting.Length -lt 12) {$null = $configContent.add("`t`t`t`t`t`t= ")} elseif ($setting.Length -lt 16) {$null = $configContent.add("`t`t`t`t`t= ")} elseif ($setting.Length -lt 20) {$null = $configContent.add("`t`t`t`t= ")} elseif ($setting.Length -lt 24) {$null = $configContent.add("`t`t`t= ")} elseif ($setting.Length -lt 28) {$null = $configContent.add("`t`t= ")} elseif ($setting.Length -lt 32) {$null = $configContent.add("`t= ")} if (($LcmSettings.$setting -eq $true) -or ($LcmSettings.$setting -eq $false)) { $null = $configContent.add("`$$($LcmSettings.$setting)") } else { $null = $configContent.add("`"$($LcmSettings.$setting)`"") } } } $null = $configContent.add("`n`t}") } $null = $configContent.add("`n}") $null = Set-Content -NoNewLine -Path $dataFilePath.FullName -Value $configContent Write-Output "`t`t$vmName - System data successfully generated." #endregion Build NodeData } $null = $jobs.add($job.Id) } #endregion if ($jobs.count -ge 1) { Write-Output "`t$resourceGroup - System data jobs created. Checking status every 30 seconds until all jobs are complete." do { $completedJobs = (Get-Job -ID $jobs | Where-Object {$_.state -ne "Running"}).count $runningjobs = (Get-Job -ID $jobs | Where-Object {$_.state -eq "Running"}).count Write-Output "`t`tSystem Data Build Status:`t$runningJobs Jobs Currently Processing`t$completedJobs/$($jobs.count) Jobs Completed" Start-Sleep -Seconds 30 } while ((Get-Job -ID $jobs).State -contains "Running") Write-Output "`n`t$($jobs.count) System data jobs completed. Outputting Results." Get-Job -ID $jobs | Wait-Job | Receive-Job } else { Write-Output "`t`tNo Jobs Generated for $resourceGroup" } } } function Publish-AzAutomationModules { <# .SYNOPSIS Publishes modules stored in the SCAR repository into an Azure Automation Account .PARAMETER RootPath Root path of the Stig Compliance Automation Repository. Initialize by running Initialize-StigRepo .PARAMETER ResourceGroupName Name of the ResourceGroup containing the targeted Azure Automation Account .PARAMETER AutomationAccountName Name of the Azure Automation Account .PARAMETER PSGallery Switch to install modules directly from the powershell gallary instead of using the modules stored in the local Stig Repository. .EXAMPLE Publish-AzAutomationModules -Rootpath "C:\StigRepo" -ResourceGroupName "My-AzAutomation-ResourceGroup" -AutomationAccountName "MyAutomationAccount" #> [CmdletBinding()] param ( [Parameter()] [string] $RootPath = (Get-Location).Path, [Parameter(Mandatory=$true)] [string] $ResourceGroupName, [Parameter(Mandatory=$true)] [string] $AutomationAccountName, [Parameter()] [switch] $PSGallery ) Write-Output "Starting Azure Automation Module Sync" # Check for Az Context $azContext = Get-AzContext -ErrorAction SilentlyContinue if ($null -eq $azContext) { Write-Output "`tAzure Subscription not connected - Follow prompt to login." Connect-AzAccount } # Get local PowerSTIG Module Version Import-Module PowerSTIG -ErrorAction SilentlyContinue $installedversion = (Get-Module PowerSTIG -ErrorAction SilentlyContinue).version.ToString() switch ($PSGallery) { $false { # Check for valid Stig-Repo Write-Output "`tChecking for valid StigRepo location at $RootPath" $modulePath = "$Rootpath\Resources\Modules" if (Test-Path "$modulePath") { Write-Output "`t`tStigRepo Location is valid" } else { Write-Output "`t`t$Rootpath is not a SCAR repository. Please point to the SCAR directory or run Initialize-StigRepo to build it." exit } # Sync DSC Modules Locally Write-Output "`tValidating local PowerSTIG Modules" Import-Module PowerSTIG -ErrorAction SilentlyContinue $stigRepoVersion = (Get-Childitem "$modulePath\PowerSTIG" -ErrorAction SilentlyContinue).name $installedversion = (Get-Module PowerSTIG -ErrorAction SilentlyContinue).version.ToString() if (($installedVersion -ne $stigRepoVersion) -or ($null -eq $installedversion)) { Write-Output "`t`tSyncing PowerSTIG Modules on localhost" Sync-DscModules -LocalHost -Force Import-Module PowerSTIG $installedVersion = (Get-Module PowerSTIG).version.tostring() } if ($null -ne $installedVersion) { Write-Output "`t`tPowerSTIG Module is valid." } else { Write-Output "`t`tError - Unable to install PowerSTIG module on the local system." exit } break } $true { Write-Output "`tValidating local PowerSTIG Modules" Import-Module StigRepo -ErrorAction SilentlyContinue $stigRepoModule = Get-Module -Name StigRepo -ErrorAction SilentlyContinue try { if ($null -ne $stigRepoModule) { Write-Output "`t`tStigRepo module is valid" } else { Write-Output "`t`tStigRepo Module not installed - Downloading from PS Gallery" Save-Module -Name StigRepo -Path "$env:SystemDrive\Program Files\WindowsPowershell\Modules" -Force Import-Module StigRepo -Force } if ($null -ne $installedVersion) { Write-Output "`t`tPowerSTIG Module is valid" } else { Write-Output "PowerSTIG Module not installed - Installing from PowerShell gallery" Save-Module -Name PowerSTIG -Path "$env:SystemDrive\Program Files\WindowsPowershell\Modules" -Force Import-Module PowerSTIG,StigRepo -Force } } catch { Write-Output "`t`tUnable to install PowerSTIG Module" Throw $_ exit } } } # Publish Modules to Azure Automation Write-Output "`tPublishing Modules to Azure Automation" # Import Modules w/ dependencies $keyModules = "PowerSTIG","VMWare.Vim","VMWare.VimAutomation.Common","StigRepo" Import-Module $keyModules $importedKeyModules = Get-Module $keyModules # Add dependent modules to array $moduleList = New-Object System.Collections.ArrayList (Get-Module VMWare.VimAutomation.Common).RequiredModules | Foreach-Object { $null = $moduleList.Add($_) } (Get-Module VMWare.Vim).RequiredModules | Foreach-Object { $null = $moduleList.Add($_) } (Get-Module PowerSTIG ).requiredModules | Foreach-Object { $null = $moduleList.Add($_) } # Add key modules to array after dependencies $importedKeyModules | Foreach-Object { $null = $moduleList.Add($_) } foreach ($module in $moduleList) { $moduleName = $module.name $moduleversion = $module.version.tostring() try { Write-Output "`t`tPublishing $moduleName Version $moduleVersion" $null = New-AzAutomationModule -Name $moduleName -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -ContentLinkUri "https://www.powershellgallery.com/api/v2/package/$moduleName/$moduleVersion" -ErrorAction Stop } catch { Write-Output "Publishing $moduleName Failed" Throw $_ } } Write-Output "`n`n`tAzure Automation Module Sync complete." } function Publish-RepoToBlob { <# .SYNOPSIS Publishes the STIG Compliance Automation Repository to Azure Blob Storage .PARAMETER RootPath Root path of the Stig Compliance Automation Repository. Initialize by running Initialize-StigRepo .PARAMETER ResourceGroupName Name of the ResourceGroup containing the targetted Azure Storage Account .PARAMETER ContainerName Name of the targetted Azure Storage Container .EXAMPLE Publish-RepoToBlob -RootPath "C:\StigRepo" -ResourceGroupName "My-Azure-ResourceGroup" -ContainerName "SCAR" #> [CmdletBinding()] param( [Parameter()] [string] $RootPath = (Get-Location).Path, [Parameter(Mandatory=$true)] [string] $ResourceGroupName, [Parameter(Mandatory=$true)] [string] $StorageAccountName = "stigstorage", [Parameter(Mandatory=$true)] [string] $ContainerName = "Scar" ) try { $systemsPath = (Resolve-Path "$rootPath\Systems").Path $configPath = (Resolve-Path "$rootPath\Configurations").Path $artifactPath = (Resolve-Path "$rootPath\Artifacts").Path $resourcePath = (Resolve-Path "$rootPath\Resources").Path } catch { Write-Output "$Rootpath is not a valid SCAR repository. Run Initialize-StigRepo to configure the repo or Set-Location to the path where it exists." exit } $context = (Get-AzStorageAccount -ResourceGroupName $ResourceGroupName -Name $StorageAccountName).Context # detect specified container name, create it if it does not exist if (-not(Get-AzStorageContainer -Context $context -Prefix $ContainerName)) { Write-Verbose -Message "Specified container does not exist, creating $ContainerName" New-AzStorageContainer -Context $context -Name $ContainerName -Permission Off | Out-Null } $scarFiles = Get-Childitem $RootPath -Recurse $scarFiles | ForEach-Object { Set-AzStorageBlobContent -Context $context -Container $ContainerName -Force } } function Register-AzAutomationNodes { <# .SYNOPSIS Registers Virtual Machines with generated System Data in SCAR as Azure Automation Nodes .PARAMETER ResourceGroupName Name of the Autmation Account ResourceGroup .PARAMETER VMResourceGroup Name of the Virtual Machine ResourceGroup .PARAMETER AutomationAccountName Name of the Azure Automation Account .EXAMPLE Register-AzAutomationNodes -ResourceGroupName "AzAutomationRG" -AutomationAccountName "MyAutomationAccount" -VMResourceGroup "VirtualMachineRG" #> [CmdletBinding()] param( [Parameter()] [string] $RootPath = (Get-Location).Path, [Parameter(Mandatory=$true)] [string] $ResourceGroupName, [Parameter(Mandatory=$true)] [string] $VMResourceGroup, [Parameter(Mandatory=$true)] [string] $AutomationAccountName ) $virtualMachines = Get-AzVM -ResourceGroupName $VMResourceGroup foreach ($virtualMachine in $virtualMachines) { Write-Output "Registering $($VirtualMachine.Name)" $configName = $virtualMachine.Name.replace("-","_") Register-AzAutomationDscNode -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -AzureVMName $virtualMachine.Name -NodeConfigurationName $configName } } function Export-AzDscConfigurations { <# .SYNOPSIS Generates PowerSTIG Configurations for system data files that are compatible with Azure Automation .PARAMETER RootPath Path to the Stig Compliance Automation Repository .EXAMPLE Export-AzDscConfigurations -RootPath "C:\StigRepo" #> [CmdletBinding()] param( [Parameter()] [string] $RootPath = (Get-Location).Path ) Write-Output "`tGenerating Azure Automation DSC Configuration Scripts" $systemFiles = Get-Childitem "$Rootpath\Systems\*.psd1" -Recurse | Where-Object FullName -notlike "*Staging*" $azConfigFolderPath = "$RootPath\Artifacts\AzConfigs" Write-Output "`t`tCreating Azure Configuration Folder - $azConfigFolderPath" $azConfigPath = (New-Item -Path $azConfigFolderPath -ItemType Directory -Force).FullName foreach ($systemFile in $systemFiles) { Write-Output "`t`t$($systemFile.BaseName) - Generating Configuration for Azure Automation" $azConfigName = $systemFile.BaseName.replace("-","_") $azConfigFile = New-Item -ItemType File -Path "$azConfigPath\$azConfigName.ps1" -Force $systemData = Invoke-Expression (Get-Content $systemFile | Out-String) [array]$configs = $systemData.AppliedConfigurations $azCOnfigString = "Configuration $($azConfigName)`n{" $azCOnfigString += "`n`tImport-DscResource -ModuleName `'PowerSTIG`'`n" $azCOnfigString += "`n`tNode `$AllNodes.Where{`$_.NodeName -eq `"$($systemFile.BaseName)`"}.NodeName`n`t{" foreach ($resource in $configs.keys) { $resourceName = $resource.Replace("PowerSTIG_","") $azConfigString += "`n`t`t$resourceName = @{" $resourceParams = $configs.$resource.keys if ($null -ne $resourceParams) { foreach ($param in $resourceParams) { $name = $param $value = $configs.$resource.$param $azConfigString += "`n`t`t`t$name = `'$value`'" } $azConfigString += "`n`t`t}`n" } else { $azConfigString += "}`n" } } $azConfigString += "`t}`n}" Set-Content $azConfigFile.FullName -Value $azConfigString -Force } Write-Output "`tAzure Automation DSC Configuration Generation Complete" } function Import-AzDscConfigurations { <# .SYNOPSIS Imports files generated by Export-AzDscConfigurations to an Azure Automation Account .PARAMETER ResourceGroupName Name of the Autmation Account ResourceGroup .PARAMETER AutomationAccountName Name of the Azure Automation Account .PARAMETER RootPath Path to the Stig Compliance Automation Repository .EXAMPLE Import-DscConfigurations -Rootpath "C:\StigRepo" -ResourceGroupName "MyAutomationAccountRG" -AutomationAccountName "MyAutomationAccount" #> [CmdletBinding()] param( [Parameter()] [string] $RootPath = (Get-Location).Path, [Parameter(Mandatory=$true)] [string] $ResourceGroupName, [Parameter(Mandatory=$true)] [string] $AutomationAccountName ) Write-Output "Starting Azure Automation import - $AutomationAccountName" try { $azConfigPath = (Resolve-Path -Path "$RootPath\Artifacts\AzConfigs" -ErrorAction 'Stop').Path $azConfigFiles = Get-Childitem "$azConfigPath\*.ps1" } catch { Write-Output "`tNo Azure DscConfiguration Files Present. Exporting Azure Automation Configuration Files." Export-AzDscConfigurations -RootPath $RootPath $azConfigPath = (Resolve-Path -Path "$RootPath\Artifacts\AzConfigs" -ErrorAction 'Stop').Path $azConfigFiles = Get-Childitem "$azConfigPath\*.ps1" } if ($null -eq (Get-AzContext)) { Write-Output "`tAzure Context not established. Follow prompt to login." Connect-AzAccount } foreach ($azConfigFile in $azConfigFiles) { $azConfigName = $azConfigFile.BaseName Write-Output "`t$($azConfigFile.BaseName) - Starting Azure Automation Sync" try { Write-Output "`t`tPublishing Configuration to Azure Automation Account" $null = Import-AzAutomationDscConfiguration -SourcePath $azConfigFile.FullName -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -Published -Force } catch { Write-Output "`t`tAzure Automation Import failed" throw $_ } try { Write-Output "`t`tCompiling Azure Automation Configuration" $null = Start-AzAutomationDscCompilationJob -ConfigurationName $azconfigName -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName } catch { Write-Output "`t`tAzure Automation Compilation Job Failed" throw $_ } } Write-Output "Azure Automation import complete" } |