Donnerstag, 23 Mai 2019 10:05

Ivanti DSM Patch Management mit PSX optimiert

Artikel bewerten
(0 Stimmen)

Jeder, der mit Ivanti DSM Patch Management arbeitet, kennt das Problem. Es gibt keine allgemeine Übersicht über alle Sicherheitslücken. Basierend auf den Jobs scannt DSM alle Computer und erstellt für jeden eine Übersicht über "Sicherheitslücken".

Basierend auf den gefundenen Sicherheitslücken weist DSM dem Computer jetzt Patch-Richtlinieninstanzen zu.

Aber woher weiß der Administrator, welche Sicherheitslücken im gesamten Netzwerk offen sind? Es ist durchaus möglich, dass eine Workstation einen Patch erhalten hat, dieser Patch ist jedoch auf 500 anderen Computern noch geöffnet.

Als Administrator haben Sie jetzt die mühsame Aufgabe, sich die Patch-Richtlinie und die Computer anzusehen, die die Richtlinie noch nicht geschlossen haben. Aber was passiert, wenn einer Sicherheitslücke aus irgendeinem Grund keine Richtlinie zugewiesen wird?

Meine Erfahrung: Man merkt es erst, wenn das Problem akut wird und es dann schnell erledigt werden muss.

Es gibt auch keine Übersicht darüber, welche Sicherheitslücken kürzlich geschlossen wurden (letzte 14 Tage oder ähnliches).

Meine Lösung - Ivanti DSM Patch Management Reporting PowerShell-Skript

Genau für diese Probleme mit dem Ivanti DSM-Patch-Management habe ich ein Powershell-Skript erstellt, das einen HTML-Bericht mit den folgenden Informationen enthält:

  • Alle Patch-Status pro Computer
  • Alle installierten Patches, die im letzten Monat installiert wurden
  • Alle Patches, die letztes Jahr installiert wurden
  • Alle Patches installiert
  • Alle offenen Patches
  • Letztes Synchronisationsdatum der Computer.

--> Jetzt noch bessere Patch Management Reports mit der  DSM Management Suite erzeugen

Diese Berichte können mithilfe von integriertem JavaScript dynamisch gefiltert werden und sind viel schneller als in der DSM-Konsole. Die Berichte können auch an das Management weitergeleitet werden, ohne dass diese Zugriff auf die DSM-Konsole erhalten.

Wichtig: Damit das Skript funktioniert, müssen die Powershell Extensions (PSX) des Unternehmens: NWC-Services installiert und ausreichend lizenziert sein. Wenn Sie die PSX PowerShell-Erweiterungen nicht kennen, besuchen Sie bitte die offizielle PSX-Website:

PSX PowerShell Extensions

Wie funktioniert das Script?

Starten Sie das Skript oder die Exe über die Befehlszeile und übergeben Sie die folgenden Parameter:

HTMLReport.ps1 –argServer „Servername:Port“ –argUser „Domain\Username“ –argPassword „Passwort“ –context "emdb:\rootDSE\Managed Users & Computers*“

Der angegebene Benutzer benötigt Rechte in der DSM-Konsole. Der Kontext repräsentiert den Organisationspfad. In diesem Kontext können Sie auch einzelne Organisationseinheiten Ihrer Organisation ansprechen. Geben Sie einfach den vollständigen OU-Pfad ein. Z.B.

"emdb:\rootDSE\Managed Users & Computers\2\. Computers\Meine Firma\Production Network\Workstations*"

Das PowerShell Script

Laden Sie datatables von JQuery herunter und legen Sie sie im selben Pfad wie das Skript ab. Andernfalls funktioniert das Sortieren und Filtern von Datensätzen nicht.

#Connection Options
param
(
    [string]$argServer = '',                    #localhost:8090
    [string]$argUser = '',                      #domain\username
    [string]$argPassword = '',                  #Password123
    [string]$loggedInUser = '',                 #Optional for Logging
    [string]$context = "emdb:\rootDSE\Managed Users & Computers\2\. Computers\*"
)

$subRoutineFlag = 0; #Default = 0 (Change only for debugging)
$patchPackageContext = "emdb:\rootDSE\Global Software Library\Patch Library\*"

$allFixedPatchPackages = @(); # Array mit allen Sicherheitslücken welche gefixt wurden

$text = "";

function WriteNavigation
{
    $ret = $ret + '<div class="navbar navbar-inverse navbar-fixed-top"><div class="container"><div class="navbar-header"></div><div class="navbar-collapse collapse"><ul class="nav navbar-nav">'
    $ret = $ret + '<li></li>'
    $ret = $ret + '<li><a href="/./Report.html">Computer Overview</a></li>'
    $ret = $ret + '<li><a href="/./SyncStatus.html">Last Syncs</a></li>'
    $ret = $ret + '<li><a href="/./PatchesMonth.html">Patches last Month</a></li>'
    $ret = $ret + '<li><a href="/./PatchesYear.html">Patches this Year</a></li>'
    $ret = $ret + '<li><a href="/./Patches.html">All installed Patches</a></li>'
    $ret = $ret + '<li><a href="/./PatchesPending.html">Open Patches</a></li>'
    $ret = $ret + '<li><a href="#">|</a></li>'
    $ret = $ret + '<li><a href="https://www.marcogriep.de">www.marcogriep.de</a></li>'
    $ret = $ret + '</ul></div></div></div><br/><br/><br/><br/><br/><br/>'

    return $ret;
}

#Prepare PS to Use HEAT DSM
import-module psx7 -DisableNameChecking

#Create global Authentification
$Server = "\\$argServer";
$Username = $argUser;
$global:path = $context
$password = $argPassword | ConvertTo-SecureString -asPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($Username, $password)

Write-Host "Using context: " + $context

#Connect to HEAT DSM
new-psdrive -name emdb -root $Server -scope script -psprovider blsemdb -Credential $credential
emdb:

# ------------------------------------------------------------------------------------------------------------------------------------------
# _____                      _ _           _____                        
#/  ___|                    (_) |         |_   _|                       
#\ `--.  ___  ___ _   _ _ __ _| |_ _   _    | | ___ ___ _   _  ___  ___ 
# `--. \/ _ \/ __| | | | '__| | __| | | |   | |/ __/ __| | | |/ _ \/ __|
#/\__/ /  __/ (__| |_| | |  | | |_| |_| |  _| |\__ \__ \ |_| |  __/\__ \
#\____/ \___|\___|\__,_|_|  |_|\__|\__, |  \___/___/___/\__,_|\___||___/
#                                   __/ |                               
#                                  |___/  
# ------------------------------------------------------------------------------------------------------------------------------------------

if ($subRoutineFlag -eq 0)
{
    #Identify all Computers
    $computers = Get-EmdbComputer $context -Recurse

    #Write HTML Header
    $text = "";
    $text = $text + '<!DOCTYPE html><html><head><title>Report</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0">'

    #Link all JavaScript Libraries & CSS Files
    $text = $text + '<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>'
    $text = $text + '<script>'
    $sr = new-object System.io.streamreader(get-item 'datatables.js')
    $text = $text + $sr.ReadToEnd()
    $text = $text + '</script>'
    $text = $text + '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">'
    $text = $text + '<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>'

    #Create Navigation
    $text = $text + '</head><body>'

    $return = WriteNavigation;
    $text = $text + $return;

    #Create a Container for HTML Body
    $text = $text + '<div class="container body-content">'

    #Write Security Issues for each Machine
    foreach ($machine in $computers)
    {
        Write-Host "Computer: " $machine.Name
        $text = $text + '<div class="entry">'
        $text = $text + '<h2>' + $machine.Name + '</h2>'
        $text = $text + '<h4>Last Sync:' + $machine.LastSyncDate + '</h4>'
        #Get-EmdbComputer $context -Name $machine.Name -Recurse | ForEach-Object { $_.GetAssociations("ComputerMissingPatch") } | Add-EmdbRelatedItem -PassThru | Format-Table @{Label="Patch"; Expression={$_.GetTargetObject().Name}}, @{Label="Status"; Expression={$_.GetPropertyValue("Status", $true, "de")}}, @{Label="Gefunden am"; Expression={$_.DetectDate}}, @{Label="Gefixt am"; Expression={$_.FixDate}} -AutoSize
        $issues = Get-EmdbComputer $context -Name $machine.Name -Recurse | ForEach-Object { $_.GetAssociations("ComputerMissingPatch") } | Add-EmdbRelatedItem -PassThru

        $text = $text + '<table class="table table-striped" border="1"><thead><tr><th>Patch</th><th>Compliance</th><th>Found</th><th>Fixed</th></tr></thead><tbody>'

        foreach ($secIssue in $issues)
        {
            Write-Host $secIssue.GetTargetObject().Name " - " $secIssue.Status
            if ($secIssue.Status -eq "NotFixed")
            {
                $text = $text + '<tr class="danger"><td>' + $secIssue.GetTargetObject().Name + '</td><td>' + $secIssue.Status + '</td><td>' + $secIssue.DetectDate + '</td><td>' + $secIssue.FixDate + '</td></tr>'
            }
            else
            {
                $text = $text + '<tr class="success"><td>' + $secIssue.GetTargetObject().Name + '</td><td>' + $secIssue.Status + '</td><td>' + $secIssue.DetectDate + '</td><td>' + $secIssue.FixDate + '</td></tr>'
            }

            if ($allFixedPatchPackages.Length -gt 0)
            {
                $found = $false
                foreach ($fixedPatch in $allFixedPatchPackages)
                {
                    if ($fixedPatch.ID -eq $secIssue.ID)
                    {
                        $found = $true;
                        break;
                    }
                    if ($fixedPatch.GetTargetObject().Name -eq $secIssue.GetTargetObject().Name)
                    {
                        $found = $true;
                        break;
                    }
                }
                if ($found -ne $true)
                {
                    $allFixedPatchPackages += $secIssue;
                }
            }
            else
            {
                $allFixedPatchPackages += $secIssue;
            }
        }
        $text = $text + '</tbody></table></div>'
    }

    $text = $text + '<blockquote class="blockquote-reverse"><p>IT Security Audit - Patch Management</p><small>Erstellt von <cite title="Griep Marco">Griep Marco</cite></small></blockquote>'
    $text = $text + '</br></br></body></html>'

    # Render Tables as Sortable Datatable through JQuery Plugin DataTables
    $text = $text + '<script>$(function(){ $("table.table").dataTable(); })</script>';

    # Write Report
    $stream = new-object IO.FileStream "C:\temp\Report.html", 'Create', 'Write', 'Read'
    $sWriter = new-object System.IO.StreamWriter $stream;
    $sWriter.Write($text);
    $sWriter.close()

    $subRoutineFlag = 1;
}

# --------------------------------------------------------------------------------------------------------------------------------------------------
#______     _       _                          _               _    ___  ___            _   _     
#| ___ \   | |     | |                        | |             | |   |  \/  |           | | | |    
#| |_/ /_ _| |_ ___| |__   ___  ___   ______  | |     __ _ ___| |_  | .  . | ___  _ __ | |_| |__  
#|  __/ _` | __/ __| '_ \ / _ \/ __| |______| | |    / _` / __| __| | |\/| |/ _ \| '_ \| __| '_ \ 
#| | | (_| | || (__| | | |  __/\__ \          | |___| (_| \__ \ |_  | |  | | (_) | | | | |_| | | |
#\_|  \__,_|\__\___|_| |_|\___||___/          \_____/\__,_|___/\__| \_|  |_/\___/|_| |_|\__|_| |_|
#                                                                                                                                                                                                    
# --------------------------------------------------------------------------------------------------------------------------------------------------

if ($subRoutineFlag -eq 1)
{
    #Write HTML Header
    $text = "";
    $text = $text + '<!DOCTYPE html><html><head><title>Report</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0">'

    #Link all JavaScript Libraries & CSS Files
    $text = $text + '<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>'
    $text = $text + '<script>'
    $sr = new-object System.io.streamreader(get-item 'datatables.js')
    $text = $text + $sr.ReadToEnd()
    $text = $text + '</script>'
    $text = $text + '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">'
    $text = $text + '<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>'

    #Create Navigation
    $text = $text + '</head><body>'

    $return = WriteNavigation;
    $text = $text + $return;

    #Create a Container for HTML Body
    $text = $text + '<div class="container body-content">'

    $text = $text + '<table class="table table-striped" border="1"><thead><tr><th>ID</th><th>Patch</th><th>Compliance</th><th>Found</th><th>Fixed</th></tr></thead><tbody>'

    $LastMonth = (Get-Date).Month-1
    $ThisYear = (Get-Date).Year

    if ($LastMonth -eq 0) # If Last month was last year
    {
        $LastMonth = 12;
        $ThisYear = $ThisYear - 1;
    }

    #$text = $text + '<tr class="success"><td>' + $secIssue.ID + '</td><td>' + $secIssue.GetTargetObject().Name + '</td><td>' + $secIssue.Status + '</td><td>' + $secIssue.DetectDate + '</td><td>' + $secIssue.FixDate + '</td></tr>'

    foreach ($secIssue in $allFixedPatchPackages)
    {
        if ($secIssue.FixDate.Year -eq $ThisYear)
        {
            if ($secIssue.FixDate.Month -eq $LastMonth)
            {
                $text = $text + '<tr class="success"><td>' + $secIssue.ID + '</td><td>' + $secIssue.GetTargetObject().Name + '</td><td>' + $secIssue.Status + '</td><td>' + $secIssue.DetectDate + '</td><td>' + $secIssue.FixDate + '</td></tr>'
            }
        }
    }

    $text = $text + '</tbody></table></div>'

    $text = $text + '<blockquote class="blockquote-reverse"><p>IT Security Audit - Patch Management</p><small>Erstellt von <cite title="Griep Marco">Griep Marco</cite></small></blockquote>'
    $text = $text + '</br></br></body></html>'

    # Render Tables as Sortable Datatable through JQuery Plugin DataTables
    $text = $text + '<script>$(function(){ $("table.table").dataTable(); })</script>';

    #Write Report
    $stream = new-object IO.FileStream "C:\temp\PatchesMonth.html", 'Create', 'Write', 'Read'
    $sWriter = new-object System.IO.StreamWriter $stream;
    $sWriter.Write($text);
    $sWriter.close()

    $subRoutineFlag = 2;
}

# --------------------------------------------------------------------------------------------------------------------------------------------------
#______     _       _                          _____                           _    __   __              
#| ___ \   | |     | |                        /  __ \                         | |   \ \ / /              
#| |_/ /_ _| |_ ___| |__   ___  ___   ______  | /  \/_   _ _ __ _ __ ___ _ __ | |_   \ V /___  __ _ _ __ 
#|  __/ _` | __/ __| '_ \ / _ \/ __| |______| | |   | | | | '__| '__/ _ \ '_ \| __|   \ // _ \/ _` | '__|
#| | | (_| | || (__| | | |  __/\__ \          | \__/\ |_| | |  | | |  __/ | | | |_    | |  __/ (_| | |   
#\_|  \__,_|\__\___|_| |_|\___||___/           \____/\__,_|_|  |_|  \___|_| |_|\__|   \_/\___|\__,_|_|   
#                                                                                                                                                                                                                                                                                                                                                                                                               
# --------------------------------------------------------------------------------------------------------------------------------------------------

if ($subRoutineFlag -eq 2)
{
    #Write HTML Header
    $text = "";
    $text = $text + '<!DOCTYPE html><html><head><title>Report</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0">'

    #Link all JavaScript Libraries & CSS Files
    $text = $text + '<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>'
    $text = $text + '<script>'
    $sr = new-object System.io.streamreader(get-item 'datatables.js')
    $text = $text + $sr.ReadToEnd()
    $text = $text + '</script>'
    $text = $text + '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">'
    $text = $text + '<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>'

    #Create Navigation
    $text = $text + '</head><body>'
    $return = WriteNavigation;
    $text = $text + $return;

    #Create a Container for HTML Body
    $text = $text + '<div class="container body-content">'

    $text = $text + '<table class="table table-striped" border="1"><thead><tr><th>ID</th><th>Patch</th><th>Compliance</th><th>Found</th><th>Fixed</th></tr></thead><tbody>'

    $LastMonth = (Get-Date).Month - 1
    $ThisYear = (Get-Date).Year

    if ($LastMonth -eq 0) # If Last month was last year
    {
        $LastMonth = 12;
        $ThisYear = $ThisYear - 1;
    }

    #$text = $text + '<tr class="success"><td>' + $secIssue.ID + '</td><td>' + $secIssue.GetTargetObject().Name + '</td><td>' + $secIssue.Status + '</td><td>' + $secIssue.DetectDate + '</td><td>' + $secIssue.FixDate + '</td></tr>'

    foreach ($secIssue in $allFixedPatchPackages)
    {
        if ($secIssue.FixDate.Year -eq $ThisYear)
        {
                $text = $text + '<tr class="success"><td>' + $secIssue.ID + '</td><td>' + $secIssue.GetTargetObject().Name + '</td><td>' + $secIssue.Status + '</td><td>' + $secIssue.DetectDate + '</td><td>' + $secIssue.FixDate + '</td></tr>'
        }
    }

    $text = $text + '</tbody></table></div>'

    $text = $text + '<blockquote class="blockquote-reverse"><p>IT Security Audit - Patch Management</p><small>Erstellt von <cite title="Griep Marco">Griep Marco</cite></small></blockquote>'
    $text = $text + '</br></br></body></html>'

    # Render Tables as Sortable Datatable through JQuery Plugin DataTables
    $text = $text + '<script>$(function(){ $("table.table").dataTable(); })</script>';

    #Write Report
    $stream = new-object IO.FileStream "C:\temp\PatchesYear.html", 'Create', 'Write', 'Read'
    $sWriter = new-object System.IO.StreamWriter $stream;
    $sWriter.Write($text);
    $sWriter.close()

    $subRoutineFlag = 3;
}

# --------------------------------------------------------------------------------------------------------------------------------------------------
#______     _       _                           ___  _ _   _____          _        _ _          _ 
#| ___ \   | |     | |                         / _ \| | | |_   _|        | |      | | |        | |
#| |_/ /_ _| |_ ___| |__   ___  ___   ______  / /_\ \ | |   | | _ __  ___| |_ __ _| | | ___  __| |
#|  __/ _` | __/ __| '_ \ / _ \/ __| |______| |  _  | | |   | || '_ \/ __| __/ _` | | |/ _ \/ _` |
#| | | (_| | || (__| | | |  __/\__ \          | | | | | |  _| || | | \__ \ || (_| | | |  __/ (_| |
#\_|  \__,_|\__\___|_| |_|\___||___/          \_| |_/_|_|  \___/_| |_|___/\__\__,_|_|_|\___|\__,_|
#                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
# --------------------------------------------------------------------------------------------------------------------------------------------------

if ($subRoutineFlag -eq 3)
{
    #Write HTML Header
    $text = "";
    $text = $text + '<!DOCTYPE html><html><head><title>Report</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0">'

    #Link all JavaScript Libraries & CSS Files
    $text = $text + '<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>'
    $text = $text + '<script>'
    $sr = new-object System.io.streamreader(get-item 'datatables.js')
    $text = $text + $sr.ReadToEnd()
    $text = $text + '</script>'
    $text = $text + '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">'
    $text = $text + '<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>'

    #Create Navigation
    $text = $text + '</head><body>'
    $return = WriteNavigation;
    $text = $text + $return;

    #Create a Container for HTML Body
    $text = $text + '<div class="container body-content">'

    $text = $text + '<table class="table table-striped" border="1"><thead><tr><th>ID</th><th>Patch</th><th>Compliance</th><th>Found</th><th>Fixed</th></tr></thead><tbody>'

    #$text = $text + '<tr class="success"><td>' + $secIssue.ID + '</td><td>' + $secIssue.GetTargetObject().Name + '</td><td>' + $secIssue.Status + '</td><td>' + $secIssue.DetectDate + '</td><td>' + $secIssue.FixDate + '</td></tr>'

    foreach ($secIssue in $allFixedPatchPackages)
    {
        if ($secIssue.Status -ne "NotFixed")
        {
            $text = $text + '<tr class="success"><td>' + $secIssue.ID + '</td><td>' + $secIssue.GetTargetObject().Name + '</td><td>' + $secIssue.Status + '</td><td>' + $secIssue.DetectDate + '</td><td>' + $secIssue.FixDate + '</td></tr>'
        }
    }

    $text = $text + '</tbody></table></div>'

    $text = $text + '<blockquote class="blockquote-reverse"><p>IT Security Audit - Patch Management</p><small>Erstellt von <cite title="Griep Marco">Griep Marco</cite></small></blockquote>'
    $text = $text + '</br></br></body></html>'

    # Render Tables as Sortable Datatable through JQuery Plugin DataTables
    $text = $text + '<script>$(function(){ $("table.table").dataTable(); })</script>';

    #Write Report
    $stream = new-object IO.FileStream "C:\temp\Patches.html", 'Create', 'Write', 'Read'
    $sWriter = new-object System.IO.StreamWriter $stream;
    $sWriter.Write($text);
    $sWriter.close()

    $subRoutineFlag = 4;
}

# --------------------------------------------------------------------------------------------------------------------------------------------------
#______              _ _              ______     _       _               
#| ___ \            | (_)             | ___ \   | |     | |              
#| |_/ /__ _ __   __| |_ _ __   __ _  | |_/ /_ _| |_ ___| |__   ___  ___ 
#|  __/ _ \ '_ \ / _` | | '_ \ / _` | |  __/ _` | __/ __| '_ \ / _ \/ __|
#| | |  __/ | | | (_| | | | | | (_| | | | | (_| | || (__| | | |  __/\__ \
#\_|  \___|_| |_|\__,_|_|_| |_|\__, | \_|  \__,_|\__\___|_| |_|\___||___/
#                               __/ |                                    
#                              |___/                                     
# --------------------------------------------------------------------------------------------------------------------------------------------------

if ($subRoutineFlag -eq 4)
{
    #Write HTML Header
    $text = "";
    $text = $text + '<!DOCTYPE html><html><head><title>Report</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0">'

    #Link all JavaScript Libraries & CSS Files
    $text = $text + '<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>'
    $text = $text + '<script>'
    $sr = new-object System.io.streamreader(get-item 'datatables.js')
    $text = $text + $sr.ReadToEnd()
    $text = $text + '</script>'
    $text = $text + '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">'
    $text = $text + '<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>'

    #Create Navigation
    $text = $text + '</head><body>'
    $return = WriteNavigation;
    $text = $text + $return;

    #Create a Container for HTML Body
    $text = $text + '<div class="container body-content">'

    $text = $text + '<table class="table table-striped" border="1"><thead><tr><th>ID</th><th>Patch</th><th>Compliance</th><th>Found</th><th>Fixed</th></tr></thead><tbody>'

    #$text = $text + '<tr class="success"><td>' + $secIssue.ID + '</td><td>' + $secIssue.GetTargetObject().Name + '</td><td>' + $secIssue.Status + '</td><td>' + $secIssue.DetectDate + '</td><td>' + $secIssue.FixDate + '</td></tr>'

    foreach ($secIssue in $allFixedPatchPackages)
    {
        if ($secIssue.Status -eq "NotFixed")
        {
            $text = $text + '<tr class="danger"><td>' + $secIssue.ID + '</td><td>' + $secIssue.GetTargetObject().Name + '</td><td>' + $secIssue.Status + '</td><td>' + $secIssue.DetectDate + '</td><td>' + $secIssue.FixDate + '</td></tr>'
        }
    }

    $text = $text + '</tbody></table></div>'

    $text = $text + '<blockquote class="blockquote-reverse"><p>IT Security Audit - Patch Management</p><small>Erstellt von <cite title="Griep Marco">Griep Marco</cite></small></blockquote>'
    $text = $text + '</br></br></body></html>'

    # Render Tables as Sortable Datatable through JQuery Plugin DataTables
    $text = $text + '<script>$(function(){ $("table.table").dataTable(); })</script>';

    #Write Report
    $stream = new-object IO.FileStream "C:\temp\PatchesPending.html", 'Create', 'Write', 'Read'
    $sWriter = new-object System.IO.StreamWriter $stream;
    $sWriter.Write($text);
    $sWriter.close()

    $subRoutineFlag = 5;
}

# --------------------------------------------------------------------------------------------------------------------------------------------------
# _____                   ______                      _   
#/  ___|                  | ___ \                    | |  
#\ `--. _   _ _ __   ___  | |_/ /___ _ __   ___  _ __| |_ 
# `--. \ | | | '_ \ / __| |    // _ \ '_ \ / _ \| '__| __|
#/\__/ / |_| | | | | (__  | |\ \  __/ |_) | (_) | |  | |_ 
#\____/ \__, |_| |_|\___| \_| \_\___| .__/ \___/|_|   \__|
#        __/ |                      | |                   
#       |___/                       |_|                   
# --------------------------------------------------------------------------------------------------------------------------------------------------

if ($subRoutineFlag -eq 5)
{
    #Identify all Computers
    $computers = Get-EmdbComputer $context -Recurse

    #Write HTML Header
    $text = "";
    $text = $text + '<!DOCTYPE html><html><head><title>Report</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0">'

    #Link all JavaScript Libraries & CSS Files
    $text = $text + '<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>'
    $text = $text + '<script>'
    $sr = new-object System.io.streamreader(get-item 'datatables.js')
    $text = $text + $sr.ReadToEnd()
    $text = $text + '</script>'
    $text = $text + '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">'
    $text = $text + '<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>'

    #Create Navigation
    $text = $text + '</head><body>'

    $return = WriteNavigation;
    $text = $text + $return;

    #Create a Container for HTML Body
    $text = $text + '<div class="container body-content">'

    #Write Security Issues for each Machine
    $text = $text + '<div class="entry">'
    $text = $text + '<h3>Sync Overview</h3>'
    $text = $text + '<table class="table table-striped" border="1"><thead><tr><th>Computer-Name</th><th>Last Sync</th></tr></thead><tbody>'

    foreach ($machine in $computers)
    {
        Write-Host "Computer: " $machine.Name
        $text = $text + '<tr class="info"><td>' + $machine.Name + '</td><td>' + $machine.LastSyncDate + '</td></tr>'
    }

    $text = $text + '</tbody></table></div>'

    $text = $text + '<div class="entry">'
    $text = $text + '<h3>Out of Sync Timeframe</h3>'
    $text = $text + '<table class="table table-striped" border="1"><thead><tr><th>Computer-Name</th><th>Last Sync</th></tr></thead><tbody>'

    $MinMonth = (Get-Date).Month - 3
    $ThisYear = (Get-Date).Year

    if ($MinMonth -lt 1) # Month can not be smaller than januar
    {
        $MinMonth = 1;
    }

    foreach ($machine in $computers)
    {

        if ($machine.LastSyncDate.Year -lt $ThisYear) # If workstation did not sync this year
        {
            $text = $text + '<tr class="danger"><td>' + $machine.Name + '</td><td>' + $machine.LastSyncDate + '</td></tr>'
        }
        else # Workstation syncted this year
        {
            if ($machine.LastSyncDate.Month -lt $MinMonth) # But not in this "acceptable" months
            {
                $text = $text + '<tr class="danger"><td>' + $machine.Name + '</td><td>' + $machine.LastSyncDate + '</td></tr>'
            }
        }
    }

    $text = $text + '</tbody></table></div>'

    $text = $text + '<blockquote class="blockquote-reverse"><p>IT Security Audit - Patch Management</p><small>Erstellt von <cite title="Griep Marco">Griep Marco</cite></small></blockquote>'
    $text = $text + '</br></br></body></html>'

    # Render Tables as Sortable Datatable through JQuery Plugin DataTables
    $text = $text + '<script>$(function(){ $("table.table").dataTable(); })</script>';

    # Write Report
    $stream = new-object IO.FileStream "C:\temp\SyncStatus.html", 'Create', 'Write', 'Read'
    $sWriter = new-object System.IO.StreamWriter $stream;
    $sWriter.Write($text);
    $sWriter.close()

    $subRoutineFlag = 6;
}



Gelesen 73 mal Letzte Änderung am Dienstag, 22 Dezember 2020 09:39

Schreibe einen Kommentar

Bitte achten Sie darauf, alle Felder mit einem Stern (*) auszufüllen. HTML-Code ist nicht erlaubt.