quinta-feira, 26 de setembro de 2019

Powershell - Job

Variables

$MaxJobs = 35
$ServerInfo = @()
$JobList =@()
$StartTime = Get-Date
$FromDateLog = Get-Date -Year 2019 -Month 8 -Day 1

Remove any old job

While (Get-Job){
    $JobRunningList = Get-Job
    Foreach ($Job in $JobRunningList){
        $($Job.ID)
        Stop-Job -Id $($Job.ID)
        Remove-Job -Id $($Job.ID)
    } 
}


Create job list

#Create a job list
ForEach ($ServerName in $ServerNameList){
        $ServerName
        $ScriptBlockName = $ServerName
        $ScriptBlock = {
            $FromDateLog = Get-Date -Year 2019 -Month 8 -Day 1
            #TimeZone
            #$TimeZone = (Get-WMIObject -Class Win32_TimeZone -Computer $args[0]).Caption
            #Bias
            #$Bias = (Get-WMIObject -Class Win32_TimeZone -Computer $args[0]).Bias
            #Uptime
            #$Uptime = [Management.ManagementDateTimeConverter]::ToDateTime((Get-WmiObject Win32_OperatingSystem -ComputerName $args[0]).LastBootUpTime)
            #Logs
            $EventLogs = Get-EventLog -ComputerName $args[0] -After $FromDateLog -LogName Security -Newest 200
            $EventLogs4724 = $EventLogs | Where-Object {($_.InstanceID -like "4724")}
            #Services
            #$ServiceList = Get-Service -ComputerName $args[0] | select -property name,starttype,status
            #$ServiceAutomaticStopped = $ServiceList | Where-Object {($_.StartType -like "Automatic") -and ($_.Status -like "Stopped")}
            # Processor utilization
            #$Processor = (Get-WmiObject -ComputerName $args[0] -Class win32_processor -ErrorAction Stop | Measure-Object -Property LoadPercentage -Average | Select-Object Average).Average
            # Memory utilization
            #$ComputerMemory = Get-WmiObject -ComputerName $args[0] -Class win32_operatingsystem -ErrorAction Stop
            #$Memory = ((($ComputerMemory.TotalVisibleMemorySize - $ComputerMemory.FreePhysicalMemory)*100)/ $ComputerMemory.TotalVisibleMemorySize)
            #$RoundMemory = [math]::Round($Memory, 2)
            #ServerObject
            $ServerInfoLine = New-Object psobject -Property @{
                                ServerName=$args[0];
                                #LastReboot=$Uptime;
                                EventLogs=$EventLogs;
                                EventLogs4724=$EventLogs2004;
                                EventLogs4724Count=$($EventLogs4724.count);
                                #ServiceList=$ServiceList;
                                #ServiceAutomaticStopped=$ServiceAutomaticStopped;
                                #TimeZone=$TimeZone;
                                #Bias=$Bias;
                                #Processor=$Processor;
                                #Memory=$Memory;
            }
            $ServerInfoLine
        }

        $JobListLine = New-Object psobject -Property @{
            Name=$ScriptBlockName;
            ScriptBlock=$ScriptBlock;
            ArgumentList=$ScriptBlockName;
        }
     
        $JobList += $JobListLine
}


Run Job List

Write-host -Object "--Running Jobs"
ForEach ($Job in $JobList){
    While ((Get-Job).count -ge $MaxJobs){
        $JobsCompletedList = Get-Job | Where {$_.State -like "Completed"}
        If ($($JobsCompletedList).count -ge 1){
            foreach ($JobCompleted in $JobsCompletedList){
                $JobOutput = Receive-Job -Name $($JobCompleted.Name)
                Remove-Job -Name $($JobCompleted.Name)
                Write-Host -Object "Added server to list: $($JobCompleted.Name)"
                $ServerInfo += $JobOutput
            }
        }
    }

    Start-Job -ScriptBlock $($Job.ScriptBlock) -Name $($Job.Name) -ArgumentList $($Job.ArgumentList) -ErrorAction Stop
}


Monitor running jobs

While ((Get-Job).count -gt 0){
    $JobsCompletedList = Get-Job | Where {$_.State -like "Completed"}
    If ($($JobsCompletedList).count -ge 1){
            foreach ($JobCompleted in $JobsCompletedList){
                $JobOutput = Receive-Job -Name $($JobCompleted.Name)
                Remove-Job -Name $($JobCompleted.Name)
                Write-Host -Object "Added server to list: $($JobCompleted.Name)"
                $ServerInfoList += $JobOutput
            }
        }
}



Job version 2

$ServerNameList = "Server01"
$JobList =@()
$MaxJobs = 2
$PatchFile = "C:\Temp\CheckPatch.ps1"

#Remove any running job
Write-host -Object "--Deleting old Jobs"
While (Get-Job){
    $JobRunningList = Get-Job
    Foreach ($Job in $JobRunningList){
        $($Job.ID)
        Stop-Job -Id $($Job.ID)
        Remove-Job -Id $($Job.ID)
    }
}


#Create Job List
ForEach($ServerName in $ServerNameList){
    $ScriptBlockName = $ServerName

    $ScriptBlock = {
        start-process powershell -ArgumentList $args[0] -Wait
    }

    $ArgumentList = "-file $PatchFile  -ServerName $ServerName -CSVReport 1"

    $JobListLine = New-Object psobject -Property @{
        Name=$ServerName;
        ScriptBlock=$ScriptBlock;
        ArgumentList=$ArgumentList;
    }

    $JobList += $JobListLine
}


#Run Jobs
Write-host -Object "--Running Jobs"
ForEach ($Job in $JobList){
    While ((Get-Job).count -ge $MaxJobs){
        $JobsCompletedList = Get-Job | Where {$_.State -like "Completed"}
        If ($($JobsCompletedList).count -ge 1){
            foreach ($JobCompleted in $JobsCompletedList){
                Remove-Job -Name $($JobCompleted.Name)
                Write-Host -Object "Added server to list: $($JobCompleted.Name)"
            }
        }
    }

    Start-Job -ScriptBlock $($Job.ScriptBlock) -Name $($Job.Name) -ArgumentList $($Job.ArgumentList) -ErrorAction Stop
}

#Monitor Runnig jobs
While ((Get-Job).count -gt 0){
    $JobsCompletedList = Get-Job | Where {$_.State -like "Completed"}
    If ($($JobsCompletedList).count -ge 1){
            foreach ($JobCompleted in $JobsCompletedList){
                Remove-Job -Name $($JobCompleted.Name)
                Write-Host -Object "Job Done: $($JobCompleted.Name)"
            }
        }
}


CheckPatch

param(
    [Parameter(Mandatory)]
    [String] $ServerName,

    [String] $PatchWindow = "XYZ",

    [String] $PatchTime = "18", #24h format

    [String] $PatchDay = "10",

    [String] $PatchMonth = "10",

    [String] $PatchYear = "2019",

    [String] $CsvPath = "C:\temp",

    [String[]] $ServiceMonitorList = @("Browser","DFSR","Netlogon","NTDS","W32Time"),

    [String[]] $SharesList = @("NETLOGON","SYSVOL"),

    [switch] $CSVReport
)

#region Variables
    $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path

    #$PatchDays = -2 #How many days before
    $AfterDate = Get-Date -day $PatchDay -Month $PatchMonth -Year $PatchYear -Hour $PatchTime -Minute 0 -Second 0
    $PatchDate = (Get-Date -day $PatchDay -Month $PatchMonth -Year $PatchYear -Hour 0 -Minute 0 -Second 0).AddHours(-5)

    $ServerInfoList = @()
    $ServiceStatus = @()
    $NotPatchedServerList = @()
    $StartTime = Get-Date
    $Today = Get-Date -Format "yyyyMMdd"
#endregion Variables

#region Get Server info
    Write-Host -Object "Geting information from server $ServerName"
    #Get Server info
    $TimeZoneObj = Get-WMIObject -Class Win32_TimeZone -Computer $ServerName

    #Server Current Time
    $MachineTime = Get-WmiObject -Class win32_localtime -ComputerName $ServerName
    $ServerCurrentTime = (Get-Date -Day $($MachineTime.Day) -Month $($MachineTime.Month) -Hour $($MachineTime.hour) -Minute $($MachineTime.minute) -Second $($MachineTime.second))
     
    #Uptime
    #$LastBoot = [Management.ManagementDateTimeConverter]::ToDateTime((Get-WmiObject Win32_OperatingSystem -ComputerName $args[0]).LastBootUpTime)
    $OS = gwmi Win32_OperatingSystem -Computername $ServerName
    $LastBoot = $OS.ConvertToDateTime($OS.LastBootUpTime)
    $UpTime = (Get-Date) - $lastBoot

    #Services
    $ServiceList = Get-Service -ComputerName $ServerName | select -property name,starttype,status

    #ShareFolders
    $ShareFolders = get-WmiObject -class Win32_Share -Computer $ServerName |Select Name,Path
     
    #Installed Updates
    $InstalledUpdates = Get-HotFix -ComputerName $ServerName

    #EventLog     
    #$EventLogs = Get-EventLog -ComputerName $ServerName -LogName System -Newest 500 -After $LastBoot
    $EventLogsDFSR = Get-EventLog -ComputerName $ServerName -LogName 'DFS Replication' -Newest 100 -After $LastBoot

    #Objects
    $ServerInfoList =  New-Object psobject -Property @{
        ServerName=$ServerName;
        TimeZone=$($TimeZoneObj.Caption);
        Bias=$($TimeZoneObj.Bias);
        Uptime=$Uptime;
        MachineTime=$MachineTime;
        ServerCurrentTime=$ServerCurrentTime;
        ServiceList=$ServiceList;
        ShareFolders=$ShareFolders;
        InstalledUpdates=$InstalledUpdates;
        EventLogs=$EventLogs;
        EventLogsDFSR=$EventLogsDFSR;
        LastBoot = $LastBoot;
    }
#endregion Get Server info

#region Check
    $ServerStatus = "Green"
    $ServerProblem = @()

    #LastBoot
    $lastBoot = $($ServerInfoList.LastBoot)
    if ($LastBoot -ge (Get-Date -day $PatchDay -Month $PatchMonth -Year $PatchYear -Hour 0 -Minute 0 -Second 0)){
        $LastRebootStatus = "Green"         
    }
    Else{
        $LastRebootStatus = "Red"
        $ServerStatus = "Red"
        $ServerProblem = "Not Rebooted."
    }
     
    #Updates
    $HotFixLast30Days = $($ServerInfoList.InstalledUpdates) | Where-Object {$_.InstalledOn -gt $PatchDate} #|Select Source,HotfixId,InstalledOn     
    if ($($HotFixLast30Days.HotFixID.Count) -gt 0){
        $InstalledUpdatesStatus = "Green"             
    }
    Else{
        $InstalledUpdatesStatus = "RED"
        $ServerStatus = "Red"
        $ServerProblem += "Not Updates installed."
    }

    #services
    #Write-Host -Object " -Service status:"
    $ServiceStatus = 0
    $ServiceList = $ServerInfoList.ServiceList
    ForEach ($Service in $ServiceMonitorList){
        If ( ($ServiceList | Where-Object {($_.Name -like "$Service")}).Status -like "Running"){
            #Write-Host -Object "   Service $Service is Running" -ForegroundColor Green
        }
        else{
            #Write-Host -Object "   Service $Service IS NOT Running" -ForegroundColor Red
            $ServiceStatus += 1
            $ServiceNotRunning += $Service
            $ServerStatus = "Red"
            $ServerProblem += "Some services are not running."
        }
    }

    #Share Folders
    $ShareFoldersStatus = 0
    $ShareFolders = $ServerInfoList.ShareFolders
    ForEach ($Share in $SharesList){
        If ($ShareFolders | Where-Object {($_.Name -like "$Share")}){
            #Write-Host -Object "   Share $Share is ok" -ForegroundColor Green
        }
        ElseIf ($ShareFolders | Where-Object {($_.Name -like "$Share")}){
            #Write-Host -Object "   Share $Share IS NOT ok" -ForegroundColor Red
            $ShareFoldersStatus += 1
            $ShareFoldersNotRunning += $Share
            $ServerStatus = "Red"
            $ServerProblem += "Some shared folders are not working."
        }
    }

    #DFS
    #$EventLogs1004 = $($ServerInfo.EventLogsDFSR) | Where-Object {($_.InstanceID -like "1073742828")}  #Event Log 1004
    #$EventLogs1210 = $($ServerInfo.EventLogsDFSR) | Where-Object {($_.InstanceID -like "1073743034")} #Event Log  1210
    #$EventLogs5722 = $($ServerInfo.EventLogsDFSR) | Where-Object {($_.InstanceID -like "5722") -and ($_.time -ge $PatchDate)}

    $EventLogs1004 = $($ServerInfo.EventLogsDFSR) | Where-Object {$_.EventID -eq '1004'} | select-object timegenerated, message, EventID -first 1
    $EventLogs1210 = $($ServerInfo.EventLogsDFSR) | Where-Object {$_.EventID -eq '1210'} | select-object timegenerated, message, EventID -first 1
#endregion Check

#region Summary
    Write-Host "Summary of server $ServerName" -BackgroundColor Black -ForegroundColor $ServerStatus

    #TimeZone and Bias
    Write-Host -Object " -TimeZone: $($ServerInfoList.TimeZone)"
    Write-Host -Object " -Bias:  $($ServerInfoList.Bias)" 

    #Server Current Time
    Write-Host -Object " -Server current time: $($ServerInfoList.ServerCurrentTime)"
     
    #Last Reboot
    Write-Host -Object " -Last reboot: $lastBoot"  -ForegroundColor $LastRebootStatus

    #Updates
    Write-host -Object " -Number of installed Hotfix After $PatchDate : $($HotFixLast30Days.HotFixID.Count)" -ForegroundColor $InstalledUpdatesStatus

    #Services
    if ($serviceStatus){
        Write-Host -Object " -Follow services ARE NOT Running: $ServiceNotRunning" -ForegroundColor Red
    }
    else{
        Write-Host -Object " -All Services are Running" -ForegroundColor Green
    }
     
    #Share Folders
    if ($ShareFoldersStatus){
        Write-Host -Object " -Some shared folders are not working: $ShareFoldersNotRunning" -ForegroundColor Red
    }
    else{
        Write-Host -Object " -All shares are OK" -ForegroundColor Green
    }

    #DFS
    if (($EventLogs1210.TimeGenerated) -gt ($EventLogs1004.TimeGenerated)){
        Write-Host " -DFRs is ok." -ForegroundColor Green
    }
    Else{
        Write-Host " -DFRS is not working." -ForegroundColor Red
    }

    Read-Host -Prompt "Press enter to continue..."

    $EndTime = Get-Date
    $TotalTime = $(($EndTime - $StartTime).TotalMinutes)
#endregion Summary

If($CSVReport){
    Write-Host "Generating CSV file in the path: $CsvPath "

    $CSVFile1List = @() #Server Info
    $CSVFile2List = @() #Updates Info

    #UpTime_Days
    $UpTime_Days = $ServerInfoList.Uptime.Days

    #UpTime_Hours
    $UpTime_Hours = $ServerInfoList.Uptime.Hours

    #Browser_Service
    $Browser_Service = ($ServerInfoList.ServiceList | Where-Object {($_.Name -like "Browser")}).Status

    #CarbonBlack_Service
    $CarbonBlack_Service = ($ServerInfoList.ServiceList | Where-Object {($_.Name -like "CarbonBlack")}).Status

    #DFSR_Service
    $DFSR_Service = ($ServerInfoList.ServiceList | Where-Object {($_.Name -like "DFSR")}).Status

    #NetLogon_Service
    $NetLogon_Service = ($ServerInfoList.ServiceList | Where-Object {($_.Name -like "Netlogon")}).Status

    #NTDS_Service
    $NTDS_Service = ($ServerInfoList.ServiceList | Where-Object {($_.Name -like "NTDS")}).Status

    #Parity_Service
    $Parity_Service = ($ServerInfoList.ServiceList | Where-Object {($_.Name -like "Parity")}).Status

    #PCNSSVC_Service
    $PCNSSVC_Service = ($ServerInfoList.ServiceList | Where-Object {($_.Name -like "pcnssvc")}).Status

    #Splunk_Service
    $Splunk_Service = ($ServerInfoList.ServiceList | Where-Object {($_.Name -like "SplunkForwarder")}).Status

    #W32Time_Service
    $W32Time_Service = ($ServerInfoList.ServiceList | Where-Object {($_.Name -like "W32Time")}).Status

    #DFS
    $EventLogs1004 = $($ServerInfoList.EventLogsDFSR) | Where-Object {$_.EventID -eq '1004'} | select-object timegenerated, message, EventID -first 1
    if ($EventLogs1004.Message){
        $DFSR_TimeGenerated = $EventLogs1004.TimeGenerated
        $DFS_Replication_Message = $EventLogs1004.Message
    }
    Else{
        $DFSR_TimeGenerated = "Not Found"
        $DFS_Replication_Message = "Not Found"
    }

    $EventLogs1210 = $($ServerInfoList.EventLogsDFSR) | Where-Object {$_.EventID -eq '1210'} | select-object timegenerated, message, EventID -first 1 
    if ($EventLogs1210.Message){
        $DFSR_Listener_Message = $EventLogs1210.Message.Split(".")[0]
        $DFSR_Listener_TimeGenerated = $EventLogs1210.TimeGenerated
    }
    Else{
        $DFSR_Listener_Message = "Not Found"
        $DFSR_Listener_TimeGenerated = "Not Found"
    }
 
    #Windows Updates
    $HotFixLastUpdateDate = $($ServerInfoList.InstalledUpdates) | Where-Object {$_.InstalledOn -gt $PatchDate}
    ForEach($Update in $($HotFixLastUpdateDate)){     
        $CSVFile2ListLine =  New-Object psobject -Property @{
            ComputerName=$($ServerInfoList.ServerName);
            InstalledOn=$($Update.InstalledOn);
            Hotfixid=$($Update.HotFixID);
            Description=$($Update.Description);
        }
        $CSVFile2List += $CSVFile2ListLine
    }
 
    #CSVFile 1
    $CSVFile1ListLine = New-Object psobject -Property @{
            ComputerName=$($ServerInfoList.ServerName);
            DC_Last_Reboot=$($ServerInfoList.LastBoot);
            UpTime_Days=$($UpTime_Days);
            UpTime_Hours=$($UpTime_Hours);
            Browser_Service=$($Browser_Service);
            CarbonBlack_Service=$($CarbonBlack_Service);
            DFSR_Service=$($DFSR_Service);
            NetLogon_Service=$($NetLogon_Service);
            NTDS_Service=$($NTDS_Service);
            Parity_Service=$($Parity_Service);
            PCNSSVC_Service=$($PCNSSVC_Service);
            Splunk_Service=$($Splunk_Service);
            W32Time_Service=$($W32Time_Service);
            DFSR_TimeGenerated=$($DFSR_TimeGenerated);
            DFS_Replication_Message=$($DFS_Replication_Message);
            DFSR_Listener_Message=$($DFSR_Listener_Message);
            DFSR_Listener_TimeGenerated=$($DFSR_Listener_TimeGenerated);
    }

    $CSVFile1ListLine | Select ComputerName,DC_Last_Reboot,UpTime_Days,UpTime_Hours,Browser_Service,CarbonBlack_Service,DFSR_Service,NetLogon_Service,NTDS_Service,Parity_Service,PCNSSVC_Service,Splunk_Service,W32Time_Service,DFSR_TimeGenerated,DFS_Replication_Message,DFSR_Listener_Message,DFSR_Listener_TimeGenerated | Export-Csv -Path "$CsvPath\$Today-Patch-ServerInfo.csv" -NoTypeInformation -Append

    $CSVFile2List | Select ComputerName,InstalledOn,Hotfixid,Description | Export-Csv -Path "$CsvPath\$Today-Patch-Updates.csv" -NoTypeInformation -Append

    Read-Host -Prompt "Press enter to continue..."
}







Nenhum comentário:

Postar um comentário