############################################################################################################################# Param ( [string]$ScriptVersion = "3.9.7", #Reporting script version [string]$SNGW #The ServiceNet gateway to be tested ) ########################################################################################################### Function ParseLine ($Line, $StartPosition, $PrimaryBreakCharacter, $AlternateBreakCharacter) # #*********************************************************************************************************** #This function is passed a string, a position in the string to start and two characters on which if #encountered the processing of the string will stop. This is used to extract information from a messy #and/or inconsistent string. #Essentially you pass it a string and tell it where you want it to stop and on what character (up to two) #you want it to stop. It will return all the characters between where you told it to start and the stop #character, not including the stop character. It also returns the position in the string where it #encountered the stop character. #*********************************************************************************************************** #> { $ResultArray=@("string",2) $CurrentLine = 0 $LineLength = $Line.Length - 1 for ($ParseLoop = $StartPosition; $ParseLoop -le $LineLength; $ParseLoop++) { If ($Line[$ParseLoop] -eq $PrimaryBreakCharacter -or $Line[$ParseLoop] -eq $AlternateBreakCharacter) { $CurrentLine = $ParseLoop $ParseLoop = $LineLength } Else { $PrimaryValue += $Line[$ParseLoop] } } #Push the character array into a string #Why not use -join? PS1 foreach ($Character in $PrimaryValue) {$EndString+=$Character} $ResultArray[0] = $PrimaryValue $ResultArray[1] = [int]$CurrentLine Return $ResultArray } ########################################################################################################### function Get-NetshInformation { #*********************************************************************************************************** #This function gathers netsh IP information for a server and returns an array with the IP address and #whether skipassource is enabled. #Note: this was set up to use custom PSObjects but unfortunately PS1 doesn't support custom PSObjects so as #we're not really doing anything with this data so far I've commented it all out and we're just saving the #data. This will be rewritten later when I actually do something with this data #*********************************************************************************************************** $Netsh = Netsh int ipv4 show ipaddresses level=verbose Set-Content 'c:\rs-pkgs\HR-Netsh-Postmigration.txt' $Netsh $TotalLines = $Netsh.length #Total length of the ipconfig /all information $CurrentLine = -1 #The current line number being processed in the ipconfig information $LineInProcess = "" #The actual line being processed $Position = 0 #Largely a placeholder variable for the parseline function, which returns two variables $IPAddress = "" #A single IP address for the current NIC $SkipasSource = $False #The string that contains a space-delimited list of IP addresses for a NIC $IPSkipAsSource = @() #Array that captures the IP and skipassource flags #Parsing the netsh information and building a simple file for post migration comparison # while ($CurrentLine -lt $TotalLines) # { # #Advancing a line in the ipconfig data and setting the line variable # $CurrentLine++ # $LineInProcess = $Netsh[$CurrentLine] # #Filtering out lines of no length, which will error # if ($LineInProcess -ne $Null) # { # Switch -casesensitive ($LineInProcess[0]) # { # "A" #In theory this is an IP address line but there are two lines that start with 'A' and the word 'Address' so we need to filter that. # { # if ($LineInProcess[19] -ne ":") # { # #This is an address line # if ($IPAddress -eq "") # { # #If the IP address variable is null then this is the first IP address so we can continue # $IPAddress = (Parseline $LineInProcess 8 "*" " ")[0] # } # else # { # #If the IP is not null then we need to collect the data and reset the variables # $IPPSO = [PSCustomObject]@{ # Address = $IPAddress; # SkipasSource = $SkipasSource # } # $IPSkipasSource += $IPPSO # $IPAddress = (Parseline $LineInProcess 8 "*" " ")[0] # $SkipasSource = $False # } # } # } # "S" #Might be SkipasSource but we'll double check # { # if ($LineInProcess[1] -eq "k") # { # #This is a skip as source line # if ($LineInProcess[21] -eq "t") # { # #If this character is t the skipassource is enabled # $SkipasSource = $True # } # } # } # } # } # } #Gathering the information for the last IP isn't going to be gathered by the above trigger # $IPPSO = [PSCustomObject]@{ # Address = $IPAddress; # SkipasSource = $SkipasSource # } # $IPSkipasSource += $IPPSO # return $IPSkipasSource return $Netsh } ########################################################################################################### function IsThis2003 { #*********************************************************************************************************** #This function determines if the subject server is running Server 2003 or not. #*********************************************************************************************************** $OSTest = wmic os list status if ($OSTest -like "*2003*") { return $True } else { Return $False } } ########################################################################################################### function IsThis2008R1 { #*********************************************************************************************************** #This function determines if the subject server is running Server 2003 or not. #*********************************************************************************************************** $OSTest = wmic os list status $ReturnValue = $False if ($OSTest -like "*2008*") { if (!($OSTest -like "*R2*")) { $ReturnValue = $True } } Return $ReturnValue } ########################################################################################################### function IsThisHyper-V { #*********************************************************************************************************** #This function determines if the subject server is running Hyper-V #*********************************************************************************************************** $Services = get-service $IsHyperV = $False foreach ($Service in $Services) { if ($HyperVTest.name -eq "vmms" -and $Service.status -ne "Disabled") { $IsHyperV = $True } } return $IsHyperV } ########################################################################################################### function Get-IPConfiguration ($NetshArray) { #*********************************************************************************************************** #This function gathers the IP information for a server and saves it at C:\rs-pkgs. #*********************************************************************************************************** #Gathering all ipconfig data and dropping it in human-readable format first just in case $IPConfig = ipconfig /all Set-Content 'c:\rs-pkgs\HR-IPConfigAll-Postmigration.txt' $IPConfig $NICData = 'c:\rs-pkgs\MR-NICData-Postmigration.csv' #file location for the pre-migration less-friendly, parsed ipconfig /all output $TotalLines = $IPConfig.length #Total length of the ipconfig /all information $CurrentLine = 0 #The current line number being processed in the ipconfig information $LineInProcess = $IPConfig[$CurrentLine] #The actual line being processed $NICName = "" #Friendly NIC name $Position = 0 #Largely a placeholder variable for the parseline function, which returns two variables $NICCount = 0 #The current count of NICs $DefaultGateway = "" #Default gateway $DNSServer = "" #A single DNS server $DNSServers = "None" #The string that contains a space-delimited list of DNS servers for a NIC $DNSServerCount = 0 #The current count of DNS servers on the current NIC $MACAddress = "" #The MAC address of the current NIC $IPAddress = "" #A single IP address for the current NIC $IPAddresses = @() #The string that contains a space-delimited list of IP addresses for a NIC $SubnetMask = "" #The subnet mask for the current NIC $SkipasSourceFlag = "" #Whether skipassource is enabled $SkipasSourceFlags = @() #All skipassource flags for all IPs #Parsing the ipconfig information and building a simple file for post migration comparison $Outline = "NICName,Description,MAC,Gateway,IPAddress,SkipasSource,DNSServers" Set-content $NICData $Outline while ($CurrentLine -lt $TotalLines) { #Advancing a line in the ipconfig data and setting the line variable $CurrentLine++ $LineInProcess = $IPConfig[$CurrentLine] #Filtering out lines of no length, which will error if ($LineInProcess -ne $Null) { if ($LineInProcess[0] -eq "E") { #Ethernet Adapter #Resetting the variables between NICs $NICName = "" $DefaultGateway = "" $DNSServer = "" $DNSServers = $Null $MACAddress = "" $IPAddress = "" $IPAddresses = @() $SubnetMask = "" $SkipasSourceFlag = "" $SkipasSourceFlags = @() $NICCount++ $NICName,$Position = (Parseline $LineInProcess 17 "*" ":")[0] } else { Switch -casesensitive ($LineInProcess[3]) { "D" #Various fields can be designated by the D here. We'll try and iron out what specifically this is. { Switch -casesensitive ($LineInProcess[6]) { #*D*es*c*ripton "c" { $NICDescription,$Position = (Parseline $LineInProcess 39 "*" ":")[0] } #*D*ef*a*ult Gateway "a" { $DefaultGateway,$Position = (Parseline $LineInProcess 39 "*" ":")[0] } #*D*NS* *Servers " " { $DNSLine = $True $DNSServer, $Position = (Parseline $LineInProcess 39 "*" "%")[0] if (!($DNSServer -like "*:*")) { #Filtering out IPv6 DNS servers. Some ServiceNet adapters have them. $DNSServers=$DNSServer } $CurrentLine++ $LineInProcess = $IPConfig[$CurrentLine] #There are likely multiple DNS servers so we'll gather each While ($DNSLine) { if ($LineInProcess[3] -eq " ") { $DNSServer, $Position = (Parseline $LineInProcess 39 "*" "%")[0] if (!($DNSServer -like "*:*")) { $DNSServers=$DNSServers+" "+$DNSServer } $CurrentLine++ $LineInProcess = $IPConfig[$CurrentLine] } Else { #As we iterate we'll go too far so we have to step back after that $CurrentLine-- $LineInProcess = $IPConfig[$CurrentLine] $DNSLine = $False } } } } } "P" #MAC Address { $MACAddress = (Parseline $LineInProcess 39 "*" ":")[0] } "I" #IP Address/es { #Making sure this is an IPv4 address if ($LineInProcess[6] -eq "4") { $IPAddress = (Parseline $LineInProcess 39 "*" "(")[0] #We'll iterate through the array that was passed by the netsh function and include the skipassource flag for this particular IP foreach ($IP in $NetshArray) { if ($IP.address -eq $IPAddress) { $SkipasSourceFlag = $IP.SkipasSource } } $IPAddresses+=$IPAddress $SkipasSourceFlags+=[string]$SkipasSourceFlag } } "S" #Subnet Mask { $SubnetMask,$Position = (Parseline $LineInProcess 39 "*" "(")[0] } "N" #NetBIOS - we don't care about this but it's the end of a particular NIC's data. It should always be there if it's an Ethernet NIC and TCP-enabled { if ($LineInProcess[6] -eq "B") { for ($i=0; $i -lt $IPAddresses.count; $i++) { $Outline = $NICName+","+$NICDescription+","+$MACAddress+","+$DefaultGateway+","+$IPAddresses[$i]+","+$SkipasSourceFlags[$i]+","+$DNSServers Add-Content $NICData $Outline } } } } } } } } ########################################################################################################### function Get-RouteInformation { #*********************************************************************************************************** #This function gathers the routing table and stores it to c:\rs-pkgs as-is. #*********************************************************************************************************** $Routes = route print Add-Content 'c:\rs-pkgs\Route-Print-Postmigration.txt' $Routes } ########################################################################################################### function Get-DiskInformation { #*********************************************************************************************************** #This function gathers information for disks presented to the OS. #*********************************************************************************************************** $Disks = Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.DriveType -ne 5} | Sort-Object -Property Name $MRDiskFile = "C:\rs-pkgs\MR-Disks-Postmigration.csv" $Outline = "Drive,Size,Free,Access,DriveType,FileSystem,MediaType,Dirty,VolumeName,Serial" Set-Content $MRDiskFile $Outline if ($Disks.Count -eq $Null) { #If there is a null count that means there is only one disk and we need to process the variable differently $Size = $Disks.Size/1GB $Size = [math]::Round($Size) $Free = $Disks.FreeSpace/1GB $Free = [math]::Round($Free) $Outline = $Disks.Name+","+$Size+","+$Free+","+$Disks.Access+","+$Disks.DriveType+","+$Disks.FileSystem+","+$Disks.MediaType+","+$Disks.VolumeDirty+","+$Disks.VolumeName+","+$Disks.VolumeSerialNumber Add-Content $MRDiskFile $Outline $Count++ } else { #Otherwise we have multiple disks and need to iterate foreach ($Disk in $Disks) { $Size = $Disk.Size/1GB $Size = [math]::Round($Size) $Free = $Disk.FreeSpace/1GB $Free = [math]::Round($Free) $Outline = $Disk.Name+","+$Size+","+$Free+","+$Disk.Access+","+$Disk.DriveType+","+$Disk.FileSystem+","+$Disk.MediaType+","+$Disk.VolumeDirty+","+$Disk.VolumeName+","+$Disk.VolumeSerialNumber Add-Content $MRDiskFile $Outline $Count++ } } if ($Count -gt 0) { return $True } else { return $False } } ########################################################################################################### function Compare-Disks { #*********************************************************************************************************** #This function compares the pre and post disk configuration. #*********************************************************************************************************** $PreFile = Import-Csv -Path "C:\rs-pkgs\MR-Disks-Premigration.csv" $PostFile = Import-Csv -Path "C:\rs-pkgs\MR-Disks-Postmigration.csv" $DisksIdentical = $True $ErrorDisks = "" $ErrorDiskCount = 0 foreach ($PreDisk in $PreFile) { $DiskFound = $False foreach ($PostDisk in $PostFile) { if ($PreDisk.Drive -eq $PostDisk.Drive -and $PreDisk.Size -eq $PostDisk.Size) {$DiskFound = $True} } if (!($DiskFound)) { $DisksIdentical = $False $ErrorDiskCount++ if ($ErrorDiskCount -eq 1) {$ErrorDisks+= $PreDisk.Drive} else {$ErrorDisks+= ","+$PreDisk.Drive} } } Return $DisksIdentical,$ErrorDisks } ########################################################################################################### function Check-rspkgs { #*********************************************************************************************************** #This function determines whether the C:\rs-pkgs file exists and is writable. #*********************************************************************************************************** $ReturnValue = $False if (!(test-path 'C:\rs-pkgs')) { new-item 'C:\rs-pkgs' -type directory | Out-Null } #Writing an empty test file new-item 'C:\rs-pkgs\MigTest.txt' -type file | Out-Null #If the new file exists we'll delete it and flag the c:\rs-pkgs as a success if (test-path 'C:\rs-pkgs\MigTest.txt') { $ReturnValue = $True remove-item 'C:\rs-pkgs\MigTest.txt' } #If the C:\rs-pkgs\Errors sub directory does not exist we'll create it now if (!(test-path "C:\rs-pkgs\Errors")) { new-item 'C:\rs-pkgs\Errors' -type directory | Out-Null } return $ReturnValue } ########################################################################################################### function IsThisACluster { #*********************************************************************************************************** #This function determines whether or not this node is part of a cluster. #*********************************************************************************************************** $Services = get-service $IsCluster = $False foreach ($Service in $Services) { if ($Service.name -eq "ClusSvc" -and $Service.status -ne "Disabled") { $IsCluster = $True } } return $IsCluster } ########################################################################################################### function IsThisTheFirstNode { #*********************************************************************************************************** #This function pulls the previous resource owners and moves the groups back to their pre-migration state. #*********************************************************************************************************** $ClusterMemberFile = "C:\rs-pkgs\MR-ClusterMembers-Premigration.csv" $ClusterNodes = import-csv $ClusterMemberFile $Hostname = hostname $FirstNodeStatus = $False if ($Hostname -eq $ClusterNodes[0].Name) { return $True } else { return $False } } ########################################################################################################### function Start-ClusterService { #*********************************************************************************************************** #This function tests to see if the cluster service is started and starts it if it exists #*********************************************************************************************************** $Test = $Null $Test = get-service -name clussvc #Checking if the cluster service actually exists and starting if it does if ($Test -eq $null) { return $False } else { Start-Service clussvc } return $True } ########################################################################################################### function Check-ClusterServiceRunning { #*********************************************************************************************************** #This function tests to see if the cluster service is started and starts it if it exists #*********************************************************************************************************** $Test = $Null $Test = get-service -name clussvc #Checking if the cluster service actually exists and starting if it does if ($Test -eq $null) { return $False } elseif ($Test.Status -eq "Running") { return $True } else { return $False } } ########################################################################################################### function Set-AutomaticClusterServices { #*********************************************************************************************************** #This function sets the cluster service to 'automatic' startup #*********************************************************************************************************** wmic service where "Name= 'ClusSvc'" call ChangeStartmode Automatic |out-null } ########################################################################################################### function Check-AutomaticClusterServices { #*********************************************************************************************************** #This function checks if the cluster service is set to 'automatic' startup #*********************************************************************************************************** $ClusterService = wmic service where "Name= 'ClusSvc'" if ($ClusterService -like "*Auto*") { return $True } else { return $False } } ############################################################################################################################# function Check-ServicenetConfig ($Gateway) { #*********************************************************************************************************** #NEED MORE #*********************************************************************************************************** #This command pings the configured gatway and returns success or failure based on the results #Had to rewrite this from using test-connection as the cmdlet doesn't exist in certain implementations $PingTest = ping $Gateway $TotalLines = $PingTest.length-1 #Total length of the ipconfig /all information $CurrentLine = 0 #The current line number being processed in the ipconfig information $Status = $False #whether or not we're able to reach the gateway #Parsing the ping information and changing the return value if we get a response while ($CurrentLine -lt $TotalLines) { if ($PingTest[$CurrentLine] -like "*Reply from*") {$Status = $True} #Advancing a line in the ipconfig data and setting the line variable $CurrentLine++ } return $Status } ########################################################################################################### function Log-Local ($LogFile,$Message) { #*********************************************************************************************************** #This function takes an array and logs locally to file. #*********************************************************************************************************** $OutFile = "C:\rs-pkgs\"+$LogFile add-content $OutFile $Message } #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#- #BEGIN SCRIPT ########################################################################################################### #Variable Initialization $Cluster = $Null #Is this device a cluster? $Hostname = hostname #Device's hostname $NetshArray = @() #Array for the IP information that comes from netsh and the skipassource checks $ResponseArray = @() #Collection of items that failed during the $ClusterGather = $False #Array to gather cluster resource groups and owners $ClusterIPGather = $False #Tracks if the various cluster gathering scripts have succeeded or failed $Hard = 0 #Number of hard errors $Soft = 0 #Number of soft errors $Success = 0 #Number of successes $ServerIs2003 = IsThis2003 #Is the server 2003 $ServerIs2008R1 = IsThis2008R1 #Is the server 2008 R1 $ServiceNetConnected = $Null #Placeholder for ServiceNet connectivity $FirstNode = $Null #Placeholder for whether or not this is the first node in a cluster $ClusterRunning = $Null #Placeholder for if the cluster service is running $DiskCheck = $Null #Disk check variable #******************************************************************************* #Testing for the existence of rs-pkgs and creating it if it's not there. If this fails we'll log to the failure array $RspkgsExists = Check-rspkgs if (!($RspkgsExists)) { $RspkgsSeverity = "hard" $RspkgsVisibility = "public" $RspkgsContext = "auditing" $RspkgsMessage = "Unable to verify C rs-pkgs. Directory still does not exist." $Hard++ } else { $RspkgsSeverity = "success" $RspkgsVisibility = "public" $RspkgsContext = "auditing" $RspkgsMessage = "C rs-pkgs exists and is writable." $Success++ } Log-local "ScriptLog - Post-Migration.txt" "Script Version:`t$ScriptVersion" #******************************************************************************* #Logging received variables Log-local "ScriptLog - Post-Migration.txt" "Parameters received." Log-local "ScriptLog - Post-Migration.txt" "Script Version:`t`t$ScriptVersion" Log-local "ScriptLog - Post-Migration.txt" "SN Gateway:`t$SNGW" #******************************************************************************* #Checking ServiceNet data #If the SNGW variable length is 0 there's no value to it so we check if it is recorded locally if ($SNGW.length -eq 0) { $AlternatePath = test-path 'c:\rs-pkgs\SNGW.txt' if ($AlternatePath) { #If we have a local file and nothing submitted from automation we'll pull the value there $SNGW = get-content 'c:\rs-pkgs\SNGW.txt' } } #After all that if our length is still zero then we don't have a ServiceNet gateway and probably never did if ($SNGW.length -eq 0 -or $SNGW.Length -eq 4) { #Log that we don't have gateway verification information $SNGWVerifySeverity = "soft" $SNGWVerifyVisibility = "public" $SNGWVerifyContext = "verification" $SNGWVerifyMessage = "No ServiceNet gateway supplied or found." $Soft++ } else { #Otherwise we do have verification information so let's test to see if everything is responding $ServiceNetConnected = Check-ServicenetConfig $SNGW If ($ServiceNetConnected) { #If it is responding then log as such $SNGWVerifySeverity = "success" $SNGWVerifyVisibility = "public" $SNGWVerifyContext = "verification" $SNGWVerifyMessage = "ServiceNet gateway is available and responding. $SNGW" $Success++ } else { #If it's not responding log a hard error $SNGWVerifySeverity = "hard" $SNGWVerifyVisibility = "public" $SNGWVerifyContext = "verification" $SNGWVerifyMessage = "ServiceNet gateway is not responding. $SNGW" $Hard++ } } #******************************************************************************* #Testing if windows patching file exists, if so proceeding to #checking windows patching service and restoring the previous setting. #Verifying windows patching service status. #If not skipping windows patching service test. $WindowsPatching = test-path 'c:\rs-pkgs\pre-patch.txt' if ($WindowsPatching) { $WindowsPatching = Get-Content 'c:\rs-pkgs\pre-patch.txt' #Enabling the service if previously running. If ($WindowsPatching -ne "Disabled") { set-service -name wuauserv -startuptype $WindowsPatching set-service -name wuauserv -status running $WindowsPatching = Get-CimInstance -ClassName Win32_Service -Filter "Name = 'wuauserv'" -Property * set-content "C:\rs-pkgs\post-patch.txt" -Value $WindowsPatching.StartMode } Else { $WindowsPatching = Get-CimInstance -ClassName Win32_Service -Filter "Name = 'wuauserv'" -Property * set-content "C:\rs-pkgs\post-patch.txt" -Value $WindowsPatching.StartMode } $WindowsPatching = Get-CimInstance -ClassName Win32_Service -Filter "Name = 'wuauserv'" -Property * #Checking the windows patching service status and reporting back. if ($WindowsPatching.StartMode -ne "Disabled") { if ($WindowsPatching.State -ne "Stopped") { $PatchingCheckSeverity = "success" $PatchingCheckVisibility = "public" $PatchingCheckContext = "qc" $PatchingCheckMessage = "Patching service is running and enabled." $Soft++ } else { $PatchingCheckSeverity = "success" $PatchingCheckVisibility = "public" $PatchingCheckContext = "qc" $PatchingCheckMessage = "Patching service is enabled but not running." $Soft++ } } else { if ($WindowsPatching.State -ne "Stopped") { $PatchingCheckSeverity = "soft" $PatchingCheckVisibility = "public" $PatchingCheckContext = "qc" $PatchingCheckMessage = "Patching service is disabled but running." $Soft++ } else { $PatchingCheckSeverity = "soft" $PatchingCheckVisibility = "public" $PatchingCheckContext = "qc" $PatchingCheckMessage = "Patching service is disabled and stopped." $Soft++ } } } else { $PatchingCheckSeverity = "soft" $PatchingCheckVisibility = "public" $PatchingCheckContext = "qc" $PatchingCheckMessage = "Pre Patch file not found." $Soft++ } #******************************************************************************* #Checking cluster status and running cluster-specific items if this device is in a cluster. If this fails we'll log to the failure array $Cluster = IsThisACluster if ($Cluster -eq $Null) { $ClusterCheckSeverity = "hard" $ClusterCheckVisibility = "public" $ClusterCheckContext = "qc" $ClusterCheckMessage = "Unable to determine if this is a cluster." $Hard++ } else { $ClusterCheckSeverity = "success" $ClusterCheckVisibility = "public" $ClusterCheckContext = "qc" $ClusterCheckMessage = "Cluster status has successfully been verified. - $Cluster" $Success++ } #******************************************************************************* #Cluster-specific commands if ($Cluster) { Import-Module failoverclusters $HyperV = IsThisHyper-V #******************************************************************************* #Setting the cluster service to Automatic but not starting said services Set-AutomaticClusterServices #Checking if this was successful $ClusterServiceGood = Check-AutomaticClusterServices if (!($ClusterServiceGood)) { #First time through failure, retrying Set-AutomaticClusterServices $ClusterServiceGood = Check-AutomaticClusterServices #Checking if our retry was successful if (!($ClusterServiceGood)) { #Logging final failure to set cluster services $ClusterAutomaticSeverity = "hard" $ClusterAutomaticVisibility = "public" $ClusterAutomaticContext = "qc" $ClusterAutomaticMessage = "Unable to set cluster services to automatic." $Hard++ } else { #Cluster service change successful. Logging. $ClusterAutomaticSeverity = "success" $ClusterAutomaticVisibility = "public" $ClusterAutomaticContext = "qc" $ClusterAutomaticMessage = "Cluster services set to automatic." $Success++ } } else { #Cluster service change successful. Logging. $ClusterAutomaticSeverity = "success" $ClusterAutomaticVisibility = "public" $ClusterAutomaticContext = "qc" $ClusterAutomaticMessage = "Cluster services set to automatic." $Success++ } if ($ServerIs2008R1 -or $ServerIs2003) { $ClusterFNSeverity = "success" $ClusterFNVisibility = "public" $ClusterFNContext = "qc" $ClusterFNMessage = "Server is 2008 R1 or prior and first node functionality is not supported yet. " $Success++ } else { #We're going to check to see if this is the first node alphabetically in the cluster. If it is we'll try to bring up the cluster on this node only $FirstNode = IsThisTheFirstNode #If the value of $FirstNode is null then something went wrong and we'll retry if ($FirstNode -eq $Null) { $FirstNode = IsThisTheFirstNode if ($FirstNode -eq $Null) { $ClusterFNSeverity = "soft" $ClusterFNVisibility = "public" $ClusterFNContext = "qc" $ClusterFNMessage = "Unable to determine if this device is the first node in the cluster" $Soft++ } else { $ClusterFNSeverity = "success" $ClusterFNVisibility = "public" $ClusterFNContext = "qc" $ClusterFNMessage = "First node cluster status identified. $FirstNode" $Success++ } } else { $ClusterFNSeverity = "success" $ClusterFNVisibility = "public" $ClusterFNContext = "qc" $ClusterFNMessage = "First node cluster status identified. $FirstNode" $Success++ } if ($FirstNode) { #This is the first node in the cluster so we're going to start the cluster service and work on bringing up the resources $ClusterRunning = Start-ClusterService if ($ClusterRunning) { $ClusterRunningSeverity = "success" $ClusterRunningVisibility = "public" $ClusterRunningContext = "qc" $ClusterRunningMessage = "Cluster service is running." $Success++ } else { $ClusterRunning = Start-ClusterService if ($ClusterRunning) { $ClusterRunningSeverity = "success" $ClusterRunningVisibility = "public" $ClusterRunningContext = "qc" $ClusterRunningMessage = "Cluster service is running." $Success++ } else { $ClusterRunningSeverity = "soft" $ClusterRunningVisibility = "public" $ClusterRunningContext = "qc" $ClusterRunningMessage = "Cluster service is not running - $ClusterRunning" $Soft++ } } } } } else { #******************************************************************************* #Gathering disk information $DiskCheck = Get-DiskInformation if (!($DiskCheck) -or $DiskCheck -eq $Null) { $DiskCheck = Get-DiskInformation if (!($DiskCheck) -or $DiskCheck -eq $Null) { $DiskCheckSeverity = "hard" $DiskCheckVisibility = "public" $DiskCheckContext = "auditing" $DiskCheckMessage = "Failure to gather disk information." $Hard++ } else { $DiskCheckSeverity = "success" $DiskCheckVisibility = "public" $DiskCheckContext = "auditing" $DiskCheckMessage = "Gathered disk information successfully." $Success++ } } else { $DiskCheckSeverity = "success" $DiskCheckVisibility = "public" $DiskCheckContext = "auditing" $DiskCheckMessage = "Gathered disk information successfully." $Success++ $DiskComparison,$NonDisks = Compare-Disks if (!($DiskComparison)) { $DiskCompSeverity = "hard" $DiskCompVisibility = "public" $DiskCompContext = "auditing" $DiskCompMessage = "Disks are not identical. Disks with issues: $NonDisks" $Hard++ } else { $DiskCompSeverity = "success" $DiskCompVisibility = "public" $DiskCompContext = "auditing" $DiskCompMessage = "Disks are identical." $Success++ } } } #******************************************************************************* #Server 2003-specific commands if ($ServerIs2003) { $NetshSeverity = "success" $NetshVisibility = "public" $NetshContext = "auditing" $NetshMessage = "Server is 2003. Netsh and skipassource data not required." $Success++ } else { #******************************************************************************* #Auditing the skipassource settings. If this fails (i.e. the first entry in the array is null we'll log to the failure array $NetshArray = Get-NetshInformation if ($NetshArray[0] -eq $Null) { $NetshSeverity = "hard" $NetshVisibility = "public" $NetshContext = "qc" $NetshMessage = "Netsh gather failure. Netsh data null" $Hard++ } else { $NetshSeverity = "success" $NetshVisibility = "public" $NetshContext = "auditing" $NetshMessage = "IP settings gathered successfully and recorded." $Success++ } } #******************************************************************************* #Gathering the IP information and storing the data locally Get-IPConfiguration $NetshArray #******************************************************************************* #Writing RBA output Write-Output "RBA START STATUS:" Write-Output "{" Write-Output "`"success`": $Success, " Write-Output "`"soft`": $Soft, " Write-Output "`"hard`": $Hard , " Write-Output "`"scriptversion`": $ScriptVersion " Write-Output "}" Write-Output "RBA END STATUS:" Write-Output "RBA START DATA:" Write-Output "[" Write-Output "`t{" Write-Output "`t`t`"scriptversion`": `"$ScriptVersion`" " Write-Output "`t}," #rs-pkgs output Write-Output "`t{" write-output "`t`t`"testname`": `"Rspkgs`"," Write-Output "`t`t`"severity`": `"$RspkgsSeverity`"," Write-Output "`t`t`"visibility`": `"$RspkgsVisibility`"," Write-Output "`t`t`"context`": `"$RspkgsContext`"," Write-Output "`t`t`"message`": `"$RspkgsMessage`"" Write-Output "`t}," #ServiceNet gateway verification change output Write-Output "`t{" write-output "`t`t`"testname`": `"ServiceNetGW`"," Write-Output "`t`t`"severity`": `"$SNGWVerifySeverity`"," Write-Output "`t`t`"visibility`": `"$SNGWVerifyVisibility`"," Write-Output "`t`t`"context`": `"$SNGWVerifyContext`"," Write-Output "`t`t`"message`": `"$SNGWVerifyMessage`"" Write-Output "`t}," #Windows patching service check output Write-Output "`t{" write-output "`t`t`"testname`": `"Patching`"," Write-Output "`t`t`"severity`": `"$PatchingCheckSeverity`"," Write-Output "`t`t`"visibility`": `"$PatchingCheckVisibility`"," Write-Output "`t`t`"context`": `"$PatchingCheckContext`"," Write-Output "`t`t`"message`": `"$PatchingCheckMessage`"" Write-Output "`t}," #Cluster status check output Write-Output "`t{" write-output "`t`t`"testname`": `"Cluster`"," Write-Output "`t`t`"severity`": `"$ClusterCheckSeverity`"," Write-Output "`t`t`"visibility`": `"$ClusterCheckVisibility`"," Write-Output "`t`t`"context`": `"$ClusterCheckContext`"," Write-Output "`t`t`"message`": `"$ClusterCheckMessage`"" Write-Output "`t}," if ($Cluster) { #Cluster service change check output Write-Output "`t{" write-output "`t`t`"testname`": `"ClusterService`"," Write-Output "`t`t`"severity`": `"$ClusterAutomaticSeverity`"," Write-Output "`t`t`"visibility`": `"$ClusterAutomaticVisibility`"," Write-Output "`t`t`"context`": `"$ClusterAutomaticContext`"," Write-Output "`t`t`"message`": `"$ClusterAutomaticMessage`"" Write-Output "`t}," #Cluster service change check output Write-Output "`t{" write-output "`t`t`"testname`": `"ClusterFirstNode`"," Write-Output "`t`t`"severity`": `"$ClusterFNSeverity`"," Write-Output "`t`t`"visibility`": `"$ClusterFNVisibility`"," Write-Output "`t`t`"context`": `"$ClusterFNContext`"," Write-Output "`t`t`"message`": `"$ClusterFNMessage`"" Write-Output "`t}," if ($FirstNode) { #Cluster service change check output Write-Output "`t{" write-output "`t`t`"testname`": `"ClusterRunning`"," Write-Output "`t`t`"severity`": `"$ClusterRunningSeverity`"," Write-Output "`t`t`"visibility`": `"$ClusterRunningVisibility`"," Write-Output "`t`t`"context`": `"$ClusterRunningContext`"," Write-Output "`t`t`"message`": `"$ClusterRunningMessage`"" Write-Output "`t}," } } else { #Disk check output write-output "`t{" write-output "`t`t`"testname`": `"DiskCheck`"," write-output "`t`t`"severity`": `"$DiskCheckSeverity`"," write-output "`t`t`"visibility`": `"$DiskCheckVisibility`"," write-output "`t`t`"context`": `"$DiskCheckContext`"," write-output "`t`t`"message`": `"$DiskCheckMessage`"" write-output "`t}," #Disk comparison output write-output "`t{" write-output "`t`t`"testname`": `"DiskComp`"," write-output "`t`t`"severity`": `"$DiskCompSeverity`"," write-output "`t`t`"visibility`": `"$DiskCompVisibility`"," write-output "`t`t`"context`": `"$DiskCompContext`"," write-output "`t`t`"message`": `"$DiskCompMessage`"" write-output "`t}," } #IP address check output Write-Output "`t{" write-output "`t`t`"testname`": `"Netsh`"," Write-Output "`t`t`"severity`": `"$NetshSeverity`"," Write-Output "`t`t`"visibility`": `"$NetshVisibility`"," Write-Output "`t`t`"context`": `"$NetshContext`"," Write-Output "`t`t`"message`": `"$NetshMessage`"" Write-Output "`t}" #Writing footer Write-Output "]" Write-Output "RBA END DATA:"