Module/STIG/Functions.BackupRevert.ps1
<#
.SYNOPSIS This function is used to backup a systems security configuration settings prior to applying PowerSTIG. .DESCRIPTION This function utilizes the get method of Invoke-Dscresource to find existing system settings. It collects the found settings and outputs into a CSV file for later use. .PARAMETER BackupLocation Specifies the location to store the backup file. .PARAMETER StigName Specifies the name of STIG to target for backup operation. The name of the STIG can be found under PowerSTIG/StigData/Processed. .NOTES This function is meant for use in a development environment .EXAMPLE Backup-StigSettings -StigName "WindowsServer-2019-MS-2.2.xml" #> function Backup-StigSettings { [CmdletBinding()] param ( [Parameter()] [ValidateScript({Test-Path -Path $_})] [string] $BackupLocation = $ENV:TEMP, [Parameter(Mandatory = $true)] [string] $StigName ) $xmlPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\StigData\Processed' $exclusion = @("*.org.default.xml","RHEL*","Ubuntu*","Vsphere*") $validStigs = Get-ChildItem $xmlPath -Exclude $exclusion if ($validStigs.Name -notContains $StigName.Trim()) { $errorArray = $validStigs.Name -join("`n") Write-Host "StigName '$($StigName.Trim())' not valid, options are :`n$errorArray" break } # Load target powerstig process xml $powerSTIGLocation = Join-Path -Path $xmlPath -ChildPath $stigName [xml] $stig = Get-Content -Path $powerSTIGLocation $ruleList = "" foreach ($validStig in $validStigs.FullName) { [xml] $stigProcess = Get-Content -Path $validStig [string[]] $ruleList += ($stigProcess.DISASTIG.ChildNodes.GetEnumerator() | Where-Object -Property dscresourcemodule -ne None).Name $rulesUnique = $rulelist | Sort-Object -Unique } $hashtable = @() foreach ($ruletype in $rulesUnique) { $rules = $stig.DISASTIG.$ruleType.Rule $dscResourceModule = $stig.DISASTIG.$ruleType.dscresourcemodule foreach ($rule in $rules) { Switch ($rule.dscResource) { AccountPolicy { $get = Invoke-DscResource -ModuleName $dscResourceModule -Name $rule.dscResource -Method get -Property @{ Name = $rule.PolicyName } $concatPolicyName = $rule.PolicyName.Replace(" ","_") $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Name" = $concatPolicyName "PolicyValue" = $get.$concatPolicyName } } AuditPolicySubcategory { $get = Invoke-DscResource -ModuleName $dscResourceModule -Name $rule.dscResource -Method get -Property @{ Name = $rule.Subcategory AuditFlag = 'success' } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Name" = $rule.Subcategory "AuditFlag" = $get.AuditFlag "Ensure" = $get.Ensure } } AuditSetting { $get = Invoke-DscResource -ModuleName $dscResourceModule -Name $rule.dscResource -Method get -Property @{ Query = $rule.Query Property = $rule.Property DesiredValue = $rule.DesiredValue Operator = $rule.Operator } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Query" = $rule.Query "Property" = $rule.Property "DesiredValue" = $get.DesiredValue "Operator" = $rule.Operator } } ProcessMitigation { $get = Invoke-DscResource -ModuleName $dscResourceModule -Name $rule.dscResource -Method get -Property @{ MitigationTarget = $rule.MitigationTarget MitigationType = $rule.MitigationType MitigationName = $rule.MitigationName MitigationValue = $rule.MitigationValue } if ($null -eq $get.MitigationValue) { $get.MitigationValue = "False" } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "MitigationTarget" = $rule.MitigationTarget "MitigationType" = $rule.MitigationType "MitigationName" = $rule.MitigationName "MitigationValue" = $get.MitigationValue } } Registry { if ($rule.key -match "HKEY_LOCAL_MACHINE") { $replace = ($rule.key).replace("HKEY_LOCAL_MACHINE","HKLM:") } else { $replace = ($rule.key).replace("HKEY_CURRENT_USER","HKCU:") } $get = Invoke-DscResource -ModuleName $dscResourceModule -Name $rule.dscResource -Method get -Property @{ Key = $replace ValueType = $rule.ValueType ValueName = $rule.ValueName } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Key" = $replace "ValueType" = $rule.ValueType "ValueName" = $rule.ValueName "ValueData" = $get.ValueData "Ensure" = $get.Ensure } } RegistryPolicyFile { if ($rule.key -match 'HKEY_CURRENT_USER') { $replace = ($rule.key).replace("HKEY_CURRENT_USER\","") $TargetType = 'UserConfiguration' } else { $replace = ($rule.key).replace("HKEY_LOCAL_MACHINE\","") $TargetType = 'ComputerConfiguration' } $get = Invoke-DscResource -ModuleName "GPRegistryPolicyDsc" -Name $rule.dscResource -Method get -Property @{ Key = $replace ValueType = $rule.ValueType ValueName = $rule.ValueName TargetType = $TargetType } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Key" = $get.Key "ValueType" = $rule.ValueType "ValueName" = $rule.ValueName "ValueData" = $get.ValueData "TargetType" = $TargetType "Ensure" = $get.Ensure } } SecurityOption { $concatOptionName = $rule.OptionName.Replace(" ","_").Replace(":","").Replace("/","_") $get = Invoke-DscResource -ModuleName $dscResourceModule -Name $rule.dscResource -Method get -Property @{ Name = $rule.OptionName } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Name" = $concatOptionName "OptionValue" = $get.$concatOptionName } } Service { if ($rule.ServiceName -ne "") { $get = Invoke-DscResource -ModuleName $dscResourceModule -Name $rule.dscResource -Method get -Property @{ Name = $rule.ServiceName } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Name" = $rule.ServiceName "StartupType" = $get.StartupType "State" = $get.State } } } UserRightsAssignment { $concatIdentityName = $rule.DisplayName.Replace(" ","_") $get = Invoke-DscResource -ModuleName $dscResourceModule -Name $rule.dscResource -Method get -Property @{ Policy = $concatIdentityName Identity = @("IdentityName") } $identityString = ($get.Identity) -join "," if ($identityString -eq "Null") { $identityString = " " } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Policy" = $concatIdentityName "Identity" = $identityString } } WindowsOptionalFeature { $get = Get-WindowsOptionalFeature -FeatureName $rule.Name -Online if ($get.State -eq "Disabled") { $ensure = "Absent" } else { $ensure = "Present" } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Name" = $rule.Name "Ensure" = $ensure } } xDnsServerSetting { $get = Invoke-DscResource -ModuleName $dscResourceModule -Name $rule.dscResource -Method get -Property @{ Name = hostname } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "NoRecursion" = $get.NoRecursion "EventLogLevel" = $get.EventLogLevel } } NTFSAccessEntry { $inputPath = [System.Environment]::ExpandEnvironmentVariables($rule.Path) $fileSystemItem = Get-Item -Path $inputPath -ErrorAction Stop $currentAcl = $fileSystemItem.GetAccessControl('Access') foreach ($entry in $currentAcl.Access) { $trimIdentity = $entry.IdentityReference -replace ".*\\" $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Path" = $rule.path "IdentityReference" = $trimIdentity "IsInherited" = $entry.IsInherited "AccessControlType" = $entry.AccessControlType "FileSystemRights" = $entry.FileSystemRights } } } RegistryAccessEntry { $inputPath = [System.Environment]::ExpandEnvironmentVariables($rule.Path) $currentACL = Get-Acl -Path $inputPath foreach ($entry in $currentAcl.Access) { $trimIdentity = $entry.IdentityReference -replace ".*\\" $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Path" = $rule.path "IdentityReference" = $trimIdentity "IsInherited" = $entry.IsInherited "AccessControlType" = $entry.AccessControlType "RegistryRights" = $entry.RegistryRights "InheritanceFlags" = $entry.InheritanceFlags "PropagationFlags" = $entry.PropagationFlags } } } CertificateDSC { $certificate = dir cert: -Recurse | Where-Object -FilterScript { $_.Thumbprint -like $rule.Thumbprint } if ($rule.CertificateName -match "Interoperability") { $storeLocation = 'Disallowed' } else { $storeLocation = 'Root' } if ($null -eq $certificate) { $Ensure = 'Absent' } else { $Ensure = 'Present' } $hashtable += @{ "DscResourceModule" = $dscResourceModule "DscResource" = $rule.dscResource "Thumbprint" = $rule.Thumbprint "Store" = $storeLocation "Location" = "LocalMachine" "Ensure" = $Ensure } } } } } #export results to csv in temp directory $path = "{0}\PowerSTIG_backup_{1}_{2}.csv" -f $BackupLocation, $StigName, (Get-Date -f MM_dd_yyyy_hh_mm_ss) $hashtable.GetEnumerator() | Select-Object -Property ` @{N='DscResourceModule';E={$_.DscResourceModule}},` @{N='DscResource';E={$_.DscResource}},` @{N='Name';E={$_.Name}},` @{N='PolicyValue';E={$_.PolicyValue}},` @{N='AuditFlag';E={$_.AuditFlag}},` @{N='Query';E={$_.Query}},@{N='Property';E={$_.Property}},` @{N='DesiredValue';E={$_.DesiredValue}},` @{N='Operator';E={$_.Operator}}, ` @{N='MitigationTarget';E={$_.MitigationTarget}}, ` @{N='MitigationType';E={$_.MitigationType}}, ` @{N='MitigationName';E={$_.MitigationName}}, ` @{N='MitigationValue';E={$_.MitigationValue}}, ` @{N='Key';E={$_.Key}}, ` @{N='ValueType';E={$_.ValueType}}, ` @{N='ValueName';E={$_.ValueName}}, ` @{N='ValueData';E={$_.ValueData}}, ` @{N='TargetType';E={$_.TargetType}}, ` @{N='Ensure';E={$_.Ensure}}, ` @{N='OptionValue';E={$_.OptionValue}}, ` @{N='StartupType';E={$_.StartupType}}, ` @{N='State';E={$_.State}}, ` @{N='Policy';E={$_.Policy}}, ` @{N='Identity';E={$_.Identity}}, ` @{N='AclObject';E={$_.AclObject}}, ` @{N='NoRecursion';E={$_.NoRecursion}}, ` @{N='EventLogLevel';E={$_.EventLogLevel}}, ` @{N='Path';E={$_.Path}}, ` @{N='IdentityReference';E={$_.IdentityReference}}, ` @{N='IsInherited';E={$_.IsInherited}}, ` @{N='AccessControlType';E={$_.AccessControlType}}, ` @{N='FileSystemRights';E={$_.FileSystemRights}}, ` @{N='RegistryRights';E={$_.RegistryRights}}, ` @{N='InheritanceFlags';E={$_.InheritanceFlags}}, ` @{N='PropagationFlags';E={$_.PropagationFlags}}, ` @{N='Store';E={$_.Store}}, ` @{N='Thumbprint';E={$_.Thumbprint}} ` | Export-Csv -NoTypeInformation -Path $path } <# .SYNOPSIS This function is used to revert to the system state at backup time. .DESCRIPTION This function utilizes the set method of Invoke-Dscresource to set the system settings using the backup. .PARAMETER BackupLocation Specifies the location to store the backup file. .PARAMETER StigName Specifies the STIG name used for backup. The name of the STIG can be found under PowerSTIG/StigData/Processed. .NOTES This function is meant for use in a development environment .EXAMPLE Restore-StigSettings -StigName "WindowsServer-2019-MS-2.2.xml" #> function Restore-StigSettings { [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'high')] param ( [Parameter()] [ValidateScript({Test-Path -Path $_})] [string] $BackupLocation = $ENV:TEMP, [Parameter(Mandatory = $true)] [string] $StigName ) $xmlPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\StigData\Processed' $exclusion = @("*.org.default.xml","RHEL*","Ubuntu*","Vsphere*") $validStigs = Get-ChildItem $xmlPath -Exclude $exclusion if ($validStigs.Name -notContains $StigName.Trim()) { $errorArray = $validStigs.Name -join("`n") Write-Host "StigName '$($StigName.Trim())' not valid, options are :`n$errorArray" break } # Remove DSC Document to revert system state if ($PSCmdlet.ShouldProcess('localhost','Restore-StigSettings')) { Remove-DscConfigurationDocument -Stage Current -Force # Get latest PowerSTIG backup $latest = Get-ChildItem -Path $BackupLocation | Where-Object -Property Name -Match $StigName | Select-Object -Last 1 $importCsv = Import-Csv -Path $latest.FullName foreach ($rule in $importCsv) { Switch ($rule.dscResource) { AccountPolicy { if ($rule.PolicyValue -match "^\d+$") { [int] $integer = $rule.PolicyValue Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Name = "Name" $rule.Name = $integer } -ErrorAction Ignore } else { Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Name = "Name" $rule.Name = $rule.PolicyValue } -ErrorAction Ignore } } AuditPolicySubcategory { if ($rule.AuditFlag -eq "No Auditing") { Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Name = $rule.Name AuditFlag = "Failure" Ensure = $rule.Ensure } Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Name = $rule.Name AuditFlag = "Success" Ensure = $rule.Ensure } } else { Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Name = $rule.Name AuditFlag = $rule.AuditFlag Ensure = $rule.Ensure } } } AuditSetting { Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Query = $rule.Query Property = $rule.Property DesiredValue = $rule.DesiredValue Operator = $rule.Operator } } ProcessMitigation { Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ MitigationTarget = $rule.MitigationTarget MitigationType = $rule.MitigationType MitigationName = $rule.MitigationName MitigationValue = $rule.MitigationValue } } Registry { [string[]] $ValueDataArray = $rule.ValueData Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Key = $rule.Key ValueType = $rule.ValueType ValueName = $rule.ValueName ValueData = $ValueDataArray Ensure = $rule.Ensure Force = $true } } RegistryPolicyFile { [string[]] $ValueDataArray = $rule.ValueData Invoke-DscResource -ModuleName "GPRegistryPolicyDsc" -Name $rule.dscResource -Method Set -Property @{ Key = $rule.Key ValueType = $rule.ValueType ValueName = $rule.ValueName TargetType = $rule.TargetType ValueData = $ValueDataArray Ensure = $rule.Ensure } if ($rule.Ensure -eq "Absent") { if ($rule.TargetType -match 'UserConfiguration') { $replace = '{0}{1}' -f "HKCU:\", $rule.key } else { $replace = '{0}{1}' -f "HKLM:\", $rule.key } Invoke-DscResource -ModuleName $rule.dscResourceModule -Name "Registry" -Method Set -Property @{ Key = $replace ValueType = $rule.ValueType ValueName = $rule.ValueName Ensure = $rule.Ensure Force = $true } } } SecurityOption { Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Name = "Name" $rule.Name = $rule.OptionValue } } Service { Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Name = $rule.Name StartupType = $rule.StartupType State = $rule.State } } UserRightsAssignment { $IdentityArray = ($rule.Identity).Split(",") Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Policy = $rule.Policy Identity = $IdentityArray Force = $true } } WindowsOptionalFeature { Invoke-DscResource -ModuleName $rule.dscResourceModule -Name $rule.dscResource -Method Set -Property @{ Name = $rule.Name Ensure = $rule.Ensure } -ErrorAction Ignore } } } } } |