Common/PowerStigScan.Main.ps1
# ----------------------------------------------------------------------------- # # Copyright (C) 2018 Microsoft Corporation # # Disclaimer: # This is SAMPLE code that is NOT production ready. It is the sole intention of this code to provide a proof of concept as a # learning tool for Microsoft Customers. Microsoft does not provide warranty for or guarantee any portion of this code # and is NOT responsible for any affects it may have on any system it is executed on or environment it resides within. # Please use this code at your own discretion! # Additional legalese: # This Sample Code is provided for the purpose of illustration only and is not intended to be used in a production environment. # THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, # INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. # We grant You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and distribute # the object code form of the Sample Code, provided that You agree: # (i) to not use Our name, logo, or trademarks to market Your software product in which the Sample Code is embedded; # (ii) to include a valid copyright notice on Your software product in which the Sample Code is embedded; and # (iii) to indemnify, hold harmless, and defend Us and Our suppliers from and against any claims or lawsuits, including attorneys' fees, # that arise or result from the use or distribution of the Sample Code. # ----------------------------------------------------------------------------- <# Functions: Private: M01 - Get-Time M02 - InsertLog M03 - Get-PowerStigXMLPath M04 - Get-PowerStigXMLVersion Public: M05 - Invoke-PowerStigScan M06 - Invoke-PowerStigBatch #> #region Private #M01 function Get-Time { return (get-date -UFormat %H:%M.%S) } #M02 function InsertLog { param( [Parameter(Mandatory=$true)] [string]$LogEntryTitle, [Parameter(Mandatory=$true)] [string]$LogMessage, [Parameter(Mandatory=$true)] [ValidateSet('Insert', 'Update', 'Delete', 'Deploy', 'Error')] [string]$ActionTaken, [Parameter(Mandatory=$true)] [String]$CMSserver, [Parameter(Mandatory=$true)] [String]$CMSDatabaseName ) $InsertLog = "EXEC PowerSTIG.sproc_InsertScanLog @LogEntryTitle = '$LogEntryTitle',@LogMessage = '$LogMessage',@ActionTaken = '$ActionTaken'" Invoke-PowerStigSqlCommand -SQLInstance $CMSserver -DatabaseName $CMSDatabaseName -query $InsertLog } #M03 function Get-PowerStigXMLPath { $powerStigXMLPath = "$($(get-module PowerSTIG).ModuleBase)\StigData\Processed" Return $powerStigXMLPath } #M04 <# .SYNOPSIS Determine the newest stig version that is in the PowerStig directory .DESCRIPTION Will pull the version number from the STIGs until the highest number is returned .PARAMETER role The role that is being tested, valid options are DC (Domain Controller), DNS, MS (Member Server), ADDomain, ADForest, IE11, and IE11 .PARAMETER osVersion Operating System version that is being targeted. Valid options are 2012R2 and 2016 .EXAMPLE Get-PowerStigXmlVersion -Role DC -osVersion 2012R2 #> function Get-PowerStigXmlVersion { [cmdletBinding()] param( [Parameter(Mandatory=$true)] [ValidateSet("DC", "DNS", "MS", "IE11", "FW", "Client", "OracleJRE", "IIS", "SQL", "Outlook2013", "PowerPoint2013", "Excel2013", "Word2013", "FireFox", "DotNet")] [string]$role, [Parameter(Mandatory=$true)] [ValidateSet("2012R2","2016","Windows-10","All")] [string]$osVersion ) [System.Array]$StigXmlBase = (get-childitem -path (Get-PowerStigXMLPath)).name # Regex pattern that tests for up to a two digit number followed by a decimal followed by up to a two digit number (i.e. 12.12,2.8,9.1) [regex]$RegexTest = "([1-9])?[0-9]\.[0-9]([0-9])?" # Holder variable for the current high value matching the previous regex $highVer = $null [System.Array]$StigXmlOs = @() # Test if the role is similar to ADDomain, ADForest, IE, or FW. If so then ensure that the OS Version is set to all if($role -eq "IE11" -or $role -eq "FW" -or $role -like "*2013" -or $role -eq "DotNet" -or $role -eq "FireFox" -or $role -eq "oracleJRE") { $osVersion = "All" } # Parse through repository for STIGs that match only the current OS that we are looking for foreach($a in $StigXMLBase) { if ($a -like "*$osVersion*") { $StigXmlOs += $a } } # If previous check returns nothing, notify the user and terminate the function if($StigXmlOs.Count -eq 0) { Write-Error -Message "No STIGs Matching Desired OS" Return $null } foreach($g in $StigXmlOs) { if($g -like "*$role*") { if($g -match $RegexTest) { [version]$wStigVer = ($RegexTest.Matches($g)).value } if($null -eq $highVer) { [version]$highVer = $wStigVer } elseif ($wStigVer -gt $highVer) { $highVer = $wStigVer } } } $stringout = $highVer.Major.ToString() + "." + $highVer.Minor.ToString() Return $stringout } #endregion Private #region Public #M05 <# .SYNOPSIS Uses PowerStig and PowerStigDSC modules to scan a target server and return data as a CSV file .DESCRIPTION Uses PowerStig and PowerStigDSC modules to scan a target server and return the data as a CSV file. The file can then be processed by the related Import-PowerStigScans script to import results into SQL. .PARAMETER ServerName Short name or FQDN of server that is to be scanned. Should ensure that WinRM is enabled on the target server prior to running .PARAMETER Role Role that is being checked for compliance. Valid Roles include MemberServer2012Check, MemberServer2016Check, DNScheck, DC2012Check, DC2016Check, and IECheck .EXAMPLE Invoke-PowerStigScan -ServerName STIGDCTest01 -Role DC2012Check Invoke-PowerStigScan -ServerName SQL2012Test -Role MemberServer2012Check #> function Invoke-PowerStigScan { [cmdletBinding()] Param( [Parameter(Mandatory=$true)] [ValidateNotNullorEmpty()] [String]$ServerName, [Parameter(Mandatory=$true,ParameterSetName="Main")] [ValidateNotNullorEmpty()] [ValidateSet("MemberServer", "DomainController", "Client", "Word", "Excel", "PowerPoint", "Outlook", "DNS", "IE", "DotNet", "FireFox", "Firewall")] [String]$Role, [Parameter(Mandatory=$true,ParameterSetName="IIS")] [ValidateNotNullorEmpty()] [ValidateSet("IIS")] [Switch]$IIS, [Parameter(Mandatory=$true,ParameterSetName="SQL")] [ValidateNotNullorEmpty()] [ValidateSet("SQL")] [Switch]$SQL, [Parameter(Mandatory=$true,ParameterSetName="IIS")] [ValidateNotNullOrEmpty()] [String]$WebsiteName, [Parameter(Mandatory=$true,ParameterSetName="IIS")] [ValidateNotNullOrEmpty()] [String]$WebAppPool, [Parameter(Mandatory=$true,ParameterSetName="SQL")] [ValidateNotNullorEmpty()] [String]$SqlInstance, [Parameter(Mandatory=$true,ParameterSetName="SQL")] [ValidateNotNullorEmpty()] [ValidateSet("Database","Instance")] [String]$SqlRole, [Parameter(Mandatory=$true,ParameterSetName="SQL")] [ValidateNotNullorEmpty()] [ValidateSet("2012")] [String]$SqlVersion, [Parameter(Mandatory=$true,ParameterSetName="SQL")] [ValidateNotNullorEmpty()] [String[]]$Database, [Parameter(Mandatory=$true,ParameterSetName="JRE")] [ValidateNotNullorEmpty()] [Switch]$JRE, [Parameter(Mandatory=$true,ParameterSetName="JRE")] [ValidateNotNullorEmpty()] [String]$ConfigurationPath, [Parameter(Mandatory=$true,ParameterSetName="JRE")] [ValidateNotNullorEmpty()] [String]$PropertiesPath, [Parameter(Mandatory=$false)] [Switch]$DebugScript ) if($PSCmdlet.ParameterSetName -eq "SQL") { $Role = "SQL" } elseif ($PSCmdlet.ParameterSetName -eq "IIS") { $Role = "IIS" } elseif ($PSCmdlet.ParameterSetName -eq "JRE") { $Role = "JRE" } ######################### #Initialize Variables # ######################### $workingPath = Split-Path $PsCommandPath $iniVar = Import-PowerStigConfig -configFilePath $workingPath\Config.ini $logDate = get-date -UFormat %m%d $logFileName = "PowerStig"+ $logDate + ".txt" $logPath = $iniVar.LogPath if(!(Test-Path -Path $logPath\$logFileName)) { $logFilePath = new-item -ItemType File -Path $logPath\$logFileName -Force } else { $logFilePath = get-item -Path $logPath\$logFileName } #Initialize Logging Add-Content $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: New Scan - $ServerName" Add-Content $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: PowerStig scan started on $ServerName for role $Role." if($DebugScript) { Add-Content $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Debug]: Config.ini Variables Are: $iniVar" Add-Content $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Debug]: WorkingPath is: $workingPath" } ############################## #Initialize Logging Complete # ############################## ############################## #Check if currently supported# ############################## if($role -eq "SQL" -or $role -eq "IIS" -or $role -eq "JRE") { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $Role is currently unavailable in this release. It will be added in an upcoming version." Return } ############################## #Test Connection to Server # ############################## #Test Connection if($DebugScript) { Add-Content $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Debug]: Running (Test-NetConnection -ComputerName $serverName -CommonTCPPort WINRM).TcpTestSucceeded -eq `$false" } if((Test-NetConnection -ComputerName $serverName -CommonTCPPort WINRM).TcpTestSucceeded -eq $false) { Add-Content -path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Error]: Connection to $serverName Failed. Check network connectivity and that the server is listening for WinRM" Return } else { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: Connection to $serverName successful" } ########################### #Test Connection Complete # ########################### ########################### #Test WSMAN Settings # ########################### if($ServerName -eq $ENV:ComputerName) { try { [int]$maxEnvelope = (get-childitem wsman:\localhost\MaxEnvelopeSizekb).value } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$Servername][$Role][ERROR]: Query for WSMAN properties failed. Check user context that this is running under." Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } else { [int]$maxEnvelope = invoke-command -ComputerName $ServerName -ScriptBlock {((get-childitem wsman:\localhost\MaxEnvelopeSizekb).value)} } #Configure WSMAN if necessary if($maxEnvelope -lt 10000 -and $ServerName -ne $ENV:ComputerName) { Add-Content -path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Warning]: Attempting to set MaxEnvelopeSizeKb on $ServerName." try { invoke-command -computername $serverName -ScriptBlock {Set-Item -Path WSMAN:\localhost\MaxEnvelopeSizekb -Value 10000} Add-Content -path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MaxEnvelopeSizeKb successfully configured on $ServerName." } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: Setting WSMAN failed on $ServerName." Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($maxEnvelope -lt 10000 -and $ServerName -eq $ENV:ComputerName) { Add-Content -path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Warning]: Attempting to set MaxEnvelopeSizeKb on $ServerName." try { Set-Item -Path WSMAN:\localhost\MaxEnvelopeSizekb -Value 10000 Add-Content -path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MaxEnvelopeSizeKb successfully configured on $ServerName." } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: Setting WSMAN failed on $ServerName." Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } else { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: WSMan is correctly configured." } ############################### #Test WSMan Settings Complete # ############################### ############################### #Convert SqlRole to DSCRole # ############################### #Determine STIG Version $dscRole = Convert-PowerStigSqlToRole -SqlRole $Role if($DebugScript) { Add-Content $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Debug]: DSCRole is $dscRole" } if(-not(test-path "$logPath\$ServerName")) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: Creating file path for this server at $logPath\$ServerName" New-Item -ItemType Directory -Path "$logpath\$ServerName" } ######################## #Convert Role Complete # ######################## ######################## #Check OSVersion # ######################## [bool]$is2012 = $true if($Role -like "*2016*") { $is2012 = $false } elseif($role -eq "Client") { $osVersion = "Windows-10" } if($is2012 -eq $true -and $osVersion -ne "Windows-10") { $osVersion = "2012R2" } elseif($is2012 -eq $false -and $osVersion -ne "Windows-10") { $osVersion = "2016" } ########################### #Check OSVersion Complete # ########################### Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: OS Version is $osVersion" #Build MOF Push-Location $logPath\$serverName ########################## #Get Stig Version Number # ########################## try { $stigVersion = Get-PowerStigXmlVersion -role $dscRole -osVersion $osVersion } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: dscRole is $dscRole" Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: osVersion is $osVersion" Return } ############################ #Get Stig Version Complete # ############################ ############################ #Create MOF # ############################ Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: Stig Version is $stigVersion" if($dscRole -eq "DNS") { #Run DNSDSC try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Debug]: Running: $workingPath\DSCConfigurations\PowerStigDNSCall.ps1 -ComputerName $ServerName -OsVersion $osVersion -StigVersion $stigVersion" } & $workingPath\DSCConfigurations\PowerStigDNSCall.ps1 -ComputerName $ServerName -OsVersion $osVersion -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $mofPath = "$logPath\$ServerName\PowerStigDNSCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "IE11") { #run IEDSC try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Debug]: Running: $workingPath\DSCConfigurations\PowerStigBrowserCall.ps1 -ComputerName $ServerName -Role $dscRole -StigVersion $stigVersion" } & $workingPath\DSCConfigurations\PowerStigBrowserCall.ps1 -ComputerName $ServerName -Role $dscRole -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $mofPath = "$logPath\$ServerName\PowerStigBrowserCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "MS" -or $dscRole -eq "DC") { #run MSDCDSC try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Debug]: Running: $workingPath\DSCConfigurations\PowerStigMSDCCall.ps1 -ComputerName $ServerName -Role $dscRole -OsVersion $osVersion -StigVersion $stigVersion" } & $workingPath\DSCConfigurations\PowerStigMSDCCall.ps1 -ComputerName $ServerName -Role $dscRole -OsVersion $osVersion -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $mofPath = "$logPath\$ServerName\PowerStigMSDCCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "FW") { try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Debug]: Running: $workingPath\DSCConfigurations\PowerStigFWCall.ps1 -ComputerName $ServerName -StigVersion $stigVersion" } & $workingPath\DSCConfigurations\PowerStigFWCall.ps1 -ComputerName $ServerName -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $mofPath = "$logPath\$ServerName\PowerStigFWCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "Word2013") { try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName[$Role][Debug]: Running: $WorkingPath\DSCConfigurations\PowerStigOfficeCall.ps1 -ComputerName $ServerName -OfficeApp $app -StigVersion $stigVersion" } & $WorkingPath\DSCConfigurations\PowerStigOfficeCall.ps1 -ComputerName $ServerName -OfficeApp $dscRole -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $MofPath = "$logPath\$ServerName\PowerStigOfficeCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "Excel2013") { try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName[$Role][Debug]: Running: $WorkingPath\DSCConfigurations\PowerStigOfficeCall.ps1 -ComputerName $ServerName -OfficeApp $app -StigVersion $stigVersion" } & $WorkingPath\DSCConfigurations\PowerStigOfficeCall.ps1 -ComputerName $ServerName -OfficeApp $dscRole -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $MofPath = "$logPath\$ServerName\PowerStigOfficeCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "PowerPoint2013") { try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName[$Role][Debug]: Running: $WorkingPath\DSCConfigurations\PowerStigOfficeCall.ps1 -ComputerName $ServerName -OfficeApp $app -StigVersion $stigVersion" } & $WorkingPath\DSCConfigurations\PowerStigOfficeCall.ps1 -ComputerName $ServerName -OfficeApp $dscRole -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $MofPath = "$logPath\$ServerName\PowerStigOfficeCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "Outlook2013") { try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName[$Role][Debug]: Running: $WorkingPath\DSCConfigurations\PowerStigOfficeCall.ps1 -ComputerName $ServerName -OfficeApp $app -StigVersion $stigVersion" } & $WorkingPath\DSCConfigurations\PowerStigOfficeCall.ps1 -ComputerName $ServerName -OfficeApp $dscRole -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $MofPath = "$logPath\$ServerName\PowerStigOfficeCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "Client") { try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName[$Role][Debug]: Running: $WorkingPath\DSCConfigurations\PowerStigWinCliCall.ps1 -ComputerName $ServerName -StigVersion $stigVersion" } & $WorkingPath\DSCConfigurations\PowerStigWinCliCall.ps1 -ComputerName $ServerName -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $MofPath = "$logPath\$ServerName\PowerStigWinCliCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "DotNet") { try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName[$Role][Debug]: Running: $WorkingPath\DSCConfigurations\PowerStigDotNetCall.ps1 -ComputerName $ServerName -StigVersion $stigVersion" } & $WorkingPath\DSCConfigurations\PowerStigDotNetCall.ps1 -ComputerName $ServerName -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $MofPath = "$logPath\$ServerName\PowerStigDotNetCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "FireFox") { try { # Determine install Directory. CurrentVersion key in Mozilla Firefox is not there in older versions, must grab folderpath name. if(invoke-command -ComputerName $ServerName -scriptblock {((get-itemproperty "HKLM:\Software\Mozilla\Mozilla Firefox").currentversion)}) { $InstallDirectory = invoke-command -ComputerName $ServerName -scriptblock {(get-itemproperty "HKLM:\Software\Mozilla\Mozilla Firefox\$((get-itemproperty "HKLM:\Software\Mozilla\Mozilla Firefox").currentversion)\Main")."Install Directory"} } else { #Grab all keys that have a version number in the name $CurrentVersions = invoke-command -ComputerName $ServerName -scriptblock {Get-ChildItem "HKLM:\Software\Mozilla\Mozilla Firefox" | Where-Object {$_.name -match "([1-9])?[0-9]\.[0-9]([0-9])?"}} [Version]$ffHighVer = 0.0.0.0 #Process through each key and determine the highest version from the list. foreach($c in $CurrentVersions) { [Version]$testVer = [regex]::match($c,"([1-9])?[0-9]\.[0-9]([0-9])?").Value if($testVer -gt $ffHighVer) { $ffHighVer = $testVer $KeyPath = $c.Name.Replace("HKEY_LOCAL_MACHINE","HKLM:") } } $InstallDirectory = invoke-command -ComputerName $ServerName -scriptblock {param($keyPath)(get-itemproperty "$keyPath\Main")."Install Directory"} -ArgumentList $keyPath } try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName[$Role][Debug]: Running: $WorkingPath\DSCConfigurations\PowerStigFiFoCall.ps1 -ComputerName $ServerName -StigVersion $stigVersion -InstallDirectory $InstallDirectory" } & $WorkingPath\DSCConfigurations\PowerStigFiFoCall.ps1 -ComputerName $ServerName -StigVersion $stigVersion -InstallDirectory $InstallDirectory Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $MofPath = "$logPath\$ServerName\PowerStigFiFoCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } <#elseif($dscRole -eq "IIS") { try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName[$Role][Debug]: Running: $WorkingPath\DSCConfigurations\PowerStigOfficeCall.ps1 -ComputerName $ServerName -OfficeApp $app -StigVersion $stigVersion" } & $WorkingPath\DSCConfigurations\PowerStigOfficeCall.ps1 -ComputerName $ServerName -OfficeApp $app -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $tempMofPath = "$logPath\$ServerName\PowerStigOfficeCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } }#> elseif($dscRole -eq "OracleJRE") { try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName[$Role][Debug]: Running: $WorkingPath\DSCConfigurations\PowerStigOraJRECall.ps1 -ComputerName $ServerName -ConfigPath $ConfigurationPath -PropertiesPath $PropertiesPath -StigVersion $stigVersion" } & $WorkingPath\DSCConfigurations\PowerStigOraJRECall.ps1 -ComputerName $ServerName -ConfigPath $ConfigurationPath -PropertiesPath $PropertiesPath -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole" $MofPath = "$logPath\$ServerName\PowerStigOraJRECall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } elseif($dscRole -eq "SQL") { try { if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName[$Role][Debug]: Running: $WorkingPath\DSCConfigurations\PowerStigSqlSerCall.ps1 -ComputerName $ServerName -SqlVersion $SqlVersion -SqlRole $SqlRole -SqlInstance $SqlInstance -Database $Database -StigVersion $stigVersion" } & $WorkingPath\DSCConfigurations\PowerStigSqlSerCall.ps1 -ComputerName $ServerName -SqlVersion $SqlVersion -SqlRole $SqlRole -SqlInstance $SqlInstance -Database $Database -StigVersion $stigVersion Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: MOF Created for $ServerName for role $dscRole, Instance $SqlInstance, Database $Database" $MofPath = "$logPath\$ServerName\PowerStigSqlSerCall" } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } } else { Add-content -Path $logFilePath -value "$(Get-Time):[$ServerName][$Role][Warning]: Skipping $dscRole on $ServerName. Role $dscRole is not a supported technology at this time." continue } if($DebugScript) { Add-Content -Path $logFilePath -value "$(Get-Time):[$ServerName][$Role][Debug]: mofPath is $mofPath" } Pop-Location #Run scan against target server $mof = get-childitem $mofPath Push-location $mofPath Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: Starting Scan for $mof" try { $scanMof = (Get-ChildItem -Path $mofPath)[0] $scanObj = Test-DscConfiguration -ComputerName $ServerName -ReferenceConfiguration $scanMof } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: mof variable is $mof" Return } Pop-Location Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: Converting results to PSObjects" try { $convertObj = Convert-PowerStigTest -TestResults $scanObj } catch { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][ERROR]: $_" Return } if($DebugScript) { Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Debug]: Object Results:" Add-Content -Path $logFilePath -Value "DesiredState`tFindingSeverity,`tStigDefinition,`tStigType,`tScanDate" foreach($o in $convertObj) { Add-Content -Path $logFilePath -Value "$($o.DesiredState),`t$($o.FindingSeverity),`t$($o.StigDefinition),`t$($o.StigType),`t$($o.ScanDate)" } } Add-Content -Path $logFilePath -Value "$(Get-Time):[$ServerName][$Role][Info]: Importing Results to Database for $ServerName and role $Role." Import-PowerStigObject -Servername $ServerName -InputObj $convertObj } #M06 function Invoke-PowerStigBatch { [CmdletBinding()] param( [Parameter(ParameterSetName='Set1',Position=0,Mandatory=$false)] [String]$cmsServer, [parameter(ParameterSetName='Set1',Position=1,Mandatory=$false)] [String]$CMSDatabaseName ) $workingPath = Split-Path $PsCommandPath $iniVar = Import-PowerStigConfig -configFilePath $workingPath\Config.ini if($null -eq $cmsServer -or $cmsServer -eq '') { $cmsServer = $iniVar.SqlInstanceName } if($null -eq $CMSDatabaseName -or $CMSDatabaseName -eq '') { $CMSDatabaseName = $iniVar.DatabaseName } #======================================================================== # Create logging functions #======================================================================== #======================================================================== # Name the PowerSTIG scan jobs #======================================================================== # This needs to be "something else", like pulled from database or not sure in a future release $JobName = "$(get-date -uformat %m%d)_PowerSTIGscan" [int]$concurrentJobs = (Get-PowerStigSqlConfig -ConcurrentScans).ConfigSetting #======================================================================== $StepName = 'Start queued scans' $StepMessage = 'Scans Started' #======================================================================== #D try { # # Logging # InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken 'UPDATE' -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName # $GetQueuedScans = "EXEC PowerStig.sproc_GetScanQueue" $RunGetQueuedScans = (Invoke-PowerStigSqlCommand -SqlInstance $cmsServer -DatabaseName $CMSDatabaseName -Query $GetQueuedScans ) $QueuedScans = @($RunGetQueuedScans) $uniqueComplianceTypes = $QueuedScans | Select-Object ComplianceType -Unique foreach($ct in $uniqueComplianceTypes) { $compTypeJobs = @($QueuedScans | Where-Object {$_.compliancetype -eq $ct.ComplianceType.ToString()}) $numJobs = $compTypeJobs.Length for($i = 0; $i -lt $numJobs;$i++) { While((Get-Job | Where-Object {$_.state -eq "Running" -and $_.name -like "*PowerSTIG*"}).count -ge $concurrentJobs) { Start-Sleep -Seconds 10 } try { $stepMessage = "Starting Job $($i+1) of $numJobs for Role $($ct.ComplianceType)" InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken 'UPDATE' -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName $TargetToScan = $compTypeJobs[$i].TargetComputer $ComplianceType = $compTypeJobs[$i].ComplianceType Start-Job -Name $JobName -scriptblock { Param ($TargetToScan, $ComplianceType) Invoke-PowerStigScan -Servername $TargetToScan -Role $ComplianceType} -ArgumentList $TargetToScan, $ComplianceType | Out-Null } catch { $StepMessage = $_.Exception.Message $StepMessage = $StepMessage -replace '['']','' InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken 'ERROR' -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName } } $StepMessage = $null $JobCount = 0 ## Wait for Jobs to Complete While((Get-Job | Where-Object {$_.state -eq "Running" -and $_.name -like "*PowerSTIG*"}).count -gt 0) { $JobCountNew = (Get-Job | Where-Object {$_.state -eq "Running" -and $_.name -like "*PowerSTIG*"}).count If($JobCountNew -ne $JobCount) { $JobCount = $JobCountNew $StepMessage = "Waiting on $JobCount jobs to finish for role $($ct.ComplianceType). Checking job status every 2 seconds." InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken 'UPDATE' -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName } Start-Sleep -Seconds 2 } } # # Logging # $StepMessage = "Scans Complete" InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken 'UPDATE' -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName # } catch { # # Logging # $StepMessage = $_.Exception.Message $StepMessage = $StepMessage -replace '['']','' InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken 'ERROR' -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName # } #======================================================================== $StepName ='Retrieve CKL path' $StepMessage = 'Retrieving CKL path from config database' #======================================================================== try { # # Logging # InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken 'UPDATE' -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName # $GetCKLpath = "EXEC PowerSTIG.sproc_GetConfigSetting @ConfigProperty = 'CKLfileLoc'" $RunGetCKLpath = (Invoke-PowerStigSqlCommand -SqlInstance $CMSserver -DatabaseName $CMSDatabaseName -Query $GetCKLpath ) $CKLpath = @($RunGetCKLpath) | Select-Object -ExpandProperty ConfigSetting # # Logging # $StepMessage = "CKL Path retrieval complete" InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken 'UPDATE' -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName # } catch { # # Logging # $StepMessage = $_.Exception.Message $StepMessage = $StepMessage -replace '['']','' InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken "ERROR" -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName # } #======================================================================== $StepName = 'Generate Checklist files (CKLs)' $StepMessage = 'Generating Checklist files' #======================================================================== try { # # Logging # InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken "UPDATE" -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName # $GetLastCKLdata = "EXEC PowerStig.sproc_GetLastDataForCKL" $RunGetLastCKLdata = (Invoke-PowerStigSqlCommand -SqlInstance $CMSserver -DatabaseName $CMSDatabaseName -Query $GetLastCKLdata ) $LastCKLdata = @($RunGetLastCKLdata) # foreach ($CKL in $LastCKLdata) { $TargetComputer = $CKL.TargetComputer $ComplianceType = $CKL.ComplianceType $Guid = $CKL.ScanGUID $Timestamp = (get-date).ToString("MMddyyyyHHmmss") $CKLfile = $CKLpath+$TargetComputer+"_"+$ComplianceType+"_"+$Timestamp+".CKL" $CKLRole = Convert-PowerStigSqlToRole -SqlRole $ComplianceType New-PowerStigCKL -Servername $TargetComputer -OSversion 2012R2 -Role $CKLRole -Outpath $CKLfile -GUID $Guid } # # Logging # InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken "UPDATE" -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName # } catch { # # Logging # $StepMessage = $_.Exception.Message $StepMessage = $StepMessage -replace '['']','' InsertLog -LogEntryTitle $StepName -LogMessage $StepMessage -ActionTaken "ERROR" -CMSServer $cmsServer -CMSDatabase $CMSDatabaseName # } } #endregion Public |