Azure VMware Solution How do I ‘monitor my SDDC deployment?’

What are we doing?

As I spend more time with my customers and my teams within my organization, I am learning that there a lot of aspects of Azure VMware Solution that we take for granted and simply skim over as we assume (badly) that everyone knows exactly how to “the basics”. With this series of “How Do I” posts, I am going to try and address some of the more common questions that I get asked and hopefully provide some useful information to help you on your Azure VMware Solution journey. I will endeavour to copy as many topics as I can and I am always open to ideas and suggestions. You can reach out to me on Twitter or post a suggestion for the log on GitHub – please remember these are designed to be short and sweet and not full blown tutorials.

For the start of this “series”, it will most likely cover topics or aspects that affect me day to day with multiple deployments and customers. As time goes on, I will try and expand the topics to cover more and more aspects of Azure VMware Solution.

How do I monitor an Azure VMware Solution deployment?

I often need to to deploy an !avsAzure VMware Solution Software Defined Data Center (SDDC) and then monitor the deployment to ensure that it is successful. I have a PowerShell script that monitors this for me and allows me to continue with other work. It works by getting the deployment status of the SDDC and then checking the status every 5 minutes until the deployment is complete. Once the deployment is complete, it will display a completed message and then you add whatever notification method you want. I save this file as deployment-check.ps1.

I am well aware and hve contributed to the Enterprise-Scale-For-AVS, these are designed to augment this or to be used on their own and are not a replacement for the Enterprise-Scale-For-AVS scripts – if used by your organization.

I do have a bit of a backlog for some of these “how-to’s” so I will try and get them out as quickly as I can. If you have any suggestions or ideas, please let me know.

<#
.SYNOPSIS
This script checks the deployment status of private clouds and monitors the provisioning process.

.DESCRIPTION
The script prompts the user to monitor a deployment or skip the deployment check. If the user chooses to monitor, it retrieves a list of private clouds and allows the user to select a private cloud to check the deployment status. It then continuously checks the provisioning status of the selected private cloud until it is no longer in the "Building" state.

.PARAMETER None

.INPUTS
None

.OUTPUTS
None

.EXAMPLE
.\deployment-check.ps1
Prompts the user to monitor a deployment and select a private cloud to check the deployment status.

.NOTES
Author: Your Name
Date: Current Date
#>

#deployment check
Write-Output "Waiting 60 seconds before checking deployment status"
Start-Sleep -s 60
$YesOrNo = Read-Host "Do you need to monitor a deployment (y/n)"
while("y","n" -notcontains $YesOrNo ) {
 $YesOrNo = Read-Host "Please enter your response (y/n)"
}
if ($YesOrNo -eq "y") {
    Write-Output "Monitoring deployment"
} else {
    Write-Output "Skipping deployment check"
    break
}


$privateClouds = Get-AzVMwarePrivateCloud
[int]$privateCloudCount = $privateClouds.count
Write-output "Found $privateCloudCount private clouds"

$i = 0
foreach ($privateCloud in $privateClouds)
{
  $cloudValue = $i
  $cloudText = [string]$cloudValue + " : " + $privateCloud.Name + " ( " + $privateCloud.ResourceGroupName + " )" + ":" + $privateCloud.Location
  Write-output $cloudText
  $i++
}
Do 
{
  [int]$privateCloudChoice = read-host -prompt "Select a private to check deployment & press enter"
} 
until ($privateCloudChoice -le $privateCloudCount)
$selectedprivateCloud = "You selected " + $privateClouds[$privateCloudChoice].Name
Write-output $selectedprivateCloud

$privateCloudRgName = $privateClouds[$privateCloudChoice].resourcegroupname
$privateCloudLocation = $privateClouds[$privateCloudChoice].location
$cloudName = $privateClouds[$privateCloudChoice].name
$privateCloud = Get-AzVMwarePrivateCloud -ResourceGroupName $privateCloudRgName -Name $cloudName


do {
    $privateCloud = Get-AzVMwarePrivateCloud -ResourceGroupName $privateCloudRgName -Name $cloudName
    $provisioningStatus = $privateCloud.provisioningState
    $timestamp = get-date -Format "dd-MM-yyyy - HH:mm:ss"
    switch ($provisioningStatus) {
        "Building" 
        {
            $statusMessage = "Provisioning status for $cloudName is : " +    $provisioningStatus + " ($timestamp)"
            Write-Output $statusMessage
            Start-Sleep -Seconds 300
       }
        "Succeeded"
        {
            $statusMessage = "Provisioning status for $cloudName is : " + $provisioningStatus + " ($timestamp)"
            Write-Output $statusMessage
            break
       }
        Default
        {
            Start-Sleep -Seconds 300
            $statusMessage = "Provisioning status for $cloudName is : " + $provisioningStatus + " ($timestamp)"
            Write-Output $statusMessage
        }
   }
   } until ($provisioningStatus -ne "Building" )

Finding off site ready tapes for System Center Data Protection Manager with System Center Orchestrator

So, I am quite a keen user of PowerShell and System Centre Orchestrator. Ok, so I recently had a request from a customer that went as follows “I need DPM to alert me when tapes are ready to  be taken off-site.”

DPM does not seen to have this functionality out of the box within the Graphical User Interface (GUI). All is NOT lost, Data Protection Manager has a PowerShell component and i was sure i could figure out a way to get this to work within PowerShell. Sure enough a solution in the form of PowerShell was found, so using this as a base, I modified the PowerShell script to suit my needs. It was also slightly modified to use with System Centre Orchestrator. The custoemr also wanted some colour and wanted the result formatted in HTML. primarily for reading purposes and auditing purposes. PowerShell code below and link here.

Import-Module DataProtectionManager
$date = Get-Date -Format "M-d-yyyy"
$path = "c:\DPMOffisteTapes\"
$filepath = $path + $date + ".html"
#creates the folder if it does not exist
New-Item -itemType file -Path $filepath
$AllLibraries = get-dpmlibrary 
$AllTapes = Get-Tape -DPMLibrary $AllLibraries
$offistereadytape = $AllTapes | Where-Object {$_.isoffsiteready -eq $true}
$a = "<style>"
$a = $a + "BODY{background-color:Green;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:GreenYellow}"
$a = $a + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:palegoldenrod}"
$a = $a + "</style>"
$offistereadytape | Select-object location, barcode , isoffsiteready|ConvertTo-Html -Head $a -Body "<H2>Offsite Ready Tapes</H2>" | out-file -FilePath $filepath

OK, so now we have the data in decent format.

image

So, with the more tapes that are ready, the more rows of data will be within the HTML.

Ok, so now we need to schedule the task. I know i could have used Task Scheduler and the like, however we have System Centre Orchestrator and with Service Management Automation available, more and more tasks will be automated. With this example, i decided to use Orchestrator.

So, I simply use a Monitor/Date Time to run the required activity at set intervals

image

I then run a DPM Script from the Data Protection Manager Integration Pack.

image

image

The filepath Variable is where the html (the full path to the html file) is written, this is especially helpful when sending the Email Message. (I know this can be done with send-mailmessage directly within the PowerShell code)

image

So there you have it, Some Orchestrator Magic with PowerShell and DPM.

(E-Mail me)

Follow me.

Facebook (Personal)

Twitter (Personal & System Centre)

Twitter (System Centre Focused)

Service Request Load Testing for SCSM

I have found a great for load testing SCSM with Incidents. The script uses SMLets to generate Incidents and you can then gauge how your system would handle the load you are planning within your Production Environment.

I will not go into the detail of the script as this blog post does a great job of explaining it. SO this got me to thinking about other Load Testing you could perform. The most common Load Test is with Incidents. However, i decided that another good load test would be Service Requests. What is nice about this load test, is that it uses a Management Pack which I have included in this post. The Management Pack contains a Service Request Template with a Manual Activity added as the first Activity. This will allow you to test Service Requests and well as Activities, which would in turn, test any workflows or runbooks that you have configured.

For my environment, i have additional runbooks which are also triggered when Manual Activities are completed or when Review Activities are completed. So with this Load Test script it also test my runbooks and other workflows.

Remember, to set a different Implementer for the Manual Activity to allow the runbooks or workflows to be triggered off correctly. Remember, no Manual Activity Implementer or if the implementer has no email address, your emails will not be triggered correctly. Below, is a breakdown of the script I am using.

Script

#SMLets is needed for the script to work
Import-Module SMlets

#the number of Service requests to be created
$SRCount = 10

#the delay between attempts
$delay = 10

# Display Start Time
$StartTime = get-date
Write-Host "Started"
Write-Host $StartTime
Write-Host "-------------------`n"
Write-Host "Creating Service Request"
Write-Host "-------------------"
$i =1

while ($i -le $SRCount)
{

#Variable / Class Setup
$srClass = Get-SCSMClass -name System.WorkItem.ServiceRequest$
$srprior = Get-SCSMEnumeration -Name ServiceRequestPriorityEnum.Medium
$srurg = Get-SCSMEnumeration -Name ServiceRequestUrgencyEnum.Medium
$ararea = get-SCSMEnumeration -Name ServiceRequestAreaEnum.Other

#building your own SR Title
$title = "Fletcher Load Testing $i - " + (get-date)

#Service Request Arguements
$srargs = @{
Title = $title;
Urgency = $srurg;
Priority = $srprior;
ID = “SR{0}”;
Area = $ararea;
Description = “Created by Script”
}

#Create Service Request
New-SCSMOBject -Class $srClass -PropertyHashtable $srargs

#Get Projection &amp; Object for Created Service Request
$srTypeProjection = Get-SCSMTypeProjection -name System.WorkItem.ServiceRequestProjection$
$SRProj = Get-scsmobjectprojection -ProjectionName $srTypeProjection.Name -filter “title -eq $title”

#Get Template
$template = Get-SCSMObjectTemplate -DisplayName "Load Test SR Template"

#Set Template
Set-SCSMObjectTemplate -Projection $SRProj -Template $template
$SR = Get-SCSMObject -Class (Get-SCSMClass -Name System.WorkItem.ServiceRequest$) -filter "Title -eq $title"
$SRName = $SR.name
$SRTitle = $SR.Title
Write-Host $SRName " - " $SRTitle
#$SRName

# Pause before creating next SR
Start-Sleep -s 5

#getting the above created Service Request
$ServiceRequestToUpdate = Get-SCSMObject -Class (Get-SCSMClass -Name System.WorkItem.ServiceRequest$) -Filter "Id -eq $SRName"

#get the Realted Child Manual Activity
$ChildActivities = (Get-SCSMRelationshipObject -BySource $ServiceRequestToUpdate | ?{$_.RelationshipID -eq "2DA498BE-0485-B2B2-D520-6EBD1698E61B"})

$get the ID Value
$MAIDToUpdate = $ChildActivities.targetobject.values[9].value

#getting the MA Class
$Class = Get-SCSMClass -Name System.WorkItem.Activity.ManualActivity

#getting the "Active" Status
$StatusActive = Get-SCSMEnumeration -name ActivityStatusEnum.Active

$Activity = Get-SCSMObject -Class $Class | ? {$_.ID -eq $MAIDToUpdate}

#setting MA to Active
Set-SCSMObject -SMObject $Activity -Property "Status" -Value $StatusActive

#showing current status
Write-host $MAIDToUpdate " is now " $StatusActive
$i +=1
Start-Sleep -s $delay
}

# Display End Time
Write-Host "_______________________`n"
$EndTime = get-date
Write-Host = "Finished"
Write-Host $EndTime
#End of Script
#

The script can also be downloaded from the Technet Gallery here.

(E-Mail me)

Follow me.

Facebook (Personal)

Twitter (Personal & System Centre)

Twitter (System Centre Focused)

Some more SMlets commands (more detail)

Would you like a nice graphical breakdown of all calls logged in (x) days and there status?

I know I would. So, of course I have been working on such a script using smlets v3.

So far, this is what the script does.

  1. Takes the current date and time and subtracts 7 days and presents you with a nice HTML output which is mailed to the user. (Both the date and time and who to mail the output to is configurable.)
  2. Uses the same date and time as configured above and creates a breakdown of all calls/cases created after said time. Provides a breakdown of these calls in terms of open, closed, resolved and all other statuses.

I am currently working on a way to automate this more and provide a breakdown of calls per user for the above timeframe as well.

Working with get-scsmincident and get-scsmclass is tricky and I am also looking for any ideas on how to achieve this. More to come as soon as possible.

Anyways, code below.

Import-Module smlets

$startdate = $(Get-Date).AddDays(-7)

#buillding folder path
$dir = $env:userprofile
$date = ((Get-Date).toString('yyyMMdd'))
$filepath = $dir.tostring() + "\" +$date + "\"
New-Item -path $filepath -ItemType Directory -ErrorAction "SilentlyContinue"

#building html style
$htmlstyle = "<style>"
$htmlstyle = $htmlstyle + "BODY{background-color:Green;}"
$htmlstyle = $htmlstyle + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$htmlstyle = $htmlstyle + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:GreenYellow}"
$htmlstyle = $htmlstyle + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:palegoldenrod}"
$htmlstyle = $htmlstyle + "</style>"

#specifying file to attach to e-mail later
$filename = $filepath + "allinc.html"

#building the file and contents of all calls and piping this out a html which will be later added to the e-mail
$createdincidentsfull = Get-SCSMIncident -CreatedAfter $startdate -ComputerName <nameoripofservicemanagerserver> |
Select-Object -Property AffectedUser, ID, Status, AssignedTo |
Sort-Object -Property Status |
ConvertTo-Html -Head $htmlstyle | Out-File $filename

#getting the information from Service Manager to supply a count of respective calls.
$createdincidents = Get-SCSMIncident -CreatedAfter $startdate -ComputerName <nameoripofservicemanagerserver>
$resolvedincidents = Get-SCSMIncident -CreatedAfter $startdate -ComputerName <nameoripofservicemanagerserver> -Status "Resolved"
$closedincidents = Get-SCSMIncident -CreatedAfter $startdate -ComputerName <nameoripofservicemanagerserver> -Status "Closed"
$countresolved = $resolvedincidents.count
$countclosed = $closedincidents.count
$countpending = $countcreated - $countresolved - $countclosed

#building message content
$line1 = "Number of calls created after" + " " + $startdate + " " + "is: " + $createdincidents.count
$line2 = "Number of calls resolved created after" + " " + $startdate + " " + "is:" + $resolvedincidents.count
$line3 = "Number of calls closed after" + " " +  $startdate + " " + "is:" + $closedincidents.count
$line4 = "Number of calls remaining open after" + " " + $startdate + " " + "is:" + $countpending

$messagecontent = @"
$line1 `r`n
$line2 `r`n
$line3 `r`n
$line4 `r`n
"@

$smtpserver = "enter IP address here"
$to = "enter recipient here"
$from = "enter sending e-mail here"
Send-MailMessage -To $to -From $from -Body $messagecontent -SmtpServer $smtpserver -Attachments $filename -Subject "Call breakdown"

File can be found here

Anyone who is interested in playing with get-scsmclass (incidents in particular).

The below might be interesting.

Get-SCSMObject -Computername "<nameoripofservicemanagerserver>" –Class (Get-SCSMClass -ComputerName <nameoripofservicemanagerserver> -Name System.WorkItem.Incident$) | gm | Format-Table -AutoSize -Wrap |Out-File <path>

 

Hope this helps,

Follow me

facebook-small32222 twitter-small32222

Get-hotfix on Steroids

Hi All,

I have taken the get-hotfix and tweaked it so something useful for my environment.

I have uploaded the .ps1 file to Technet.

My script can be found here

#building options for computer names
Write-host "How do you want to enter computer names?"
Write-host "1 = File with Comnputer names?"
Write-host "2 = Enter manually?"
Write-host ""
$choices1 = Read-host "Enter your choice"

switch ($choices1)
{
    1
        {
            $computernamefile = Read-host "Please enter file path"
            
            $computernames = (Get-Content -Path $computernamefile)
        }
    2
        {
            $computernames = (Read-Host "Enter the Computer Name(s) (separate with a comma)").split(',') | %{$_.trim()}
        }
    default
        {
            Write-Host "Invalid selection"
            Write-Host "Assuming you want to enter manually"
            $computernames = (Read-Host "Enter the Computer Name(s) (separate with a comma)").split(',') | %{$_.trim()}
        }
}

#get username
$cred = $host.ui.PromptForCredential("Need credentials", "Please enter your user name and password.", "", "NetBiosUserName")


#building in choices
write-host ""
Write-Host "======================================"
Write-Host "What type of fix are you looking for?"
Write-host "1 = Hotfix"
Write-host "2 = Security update"
Write-host "3 = Update"
Write-host "4 = Service Pack"
Write-host "5 = All"
Write-host "======================================"
Write-host ""
$choice = Read-host "Please enter choice"

#building html style
$htmlstyle = "<style>"
$htmlstyle = $htmlstyle + "BODY{background-color:Green;}"
$htmlstyle = $htmlstyle + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$htmlstyle = $htmlstyle + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:GreenYellow}"
$htmlstyle = $htmlstyle + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:palegoldenrod}"
$htmlstyle = $htmlstyle + "</style>"

#buillding folder path
$dir = $env:userprofile
$date = ((Get-Date).toString('yyyMMdd'))

#creating email addresses for recipeint
$recipeint = $env:username
$recipeint = $recipeint + "@europcar.co.za"
$recipeint

#creating email addresses for sender
$sender = $env:username
$sender = $sender + "@europcar.co.za"
$sender

#get-hotfixes
switch ($choice)
{
    1 
        {
            foreach ($computername in $computernames)
            {
                $filenamehtml = "hotfixes.html"
                $filenametxt = "hotfixes.txt"
                $newfolderpath = $dir.tostring() + "\" +$date + "\" + $computername + "\"
                New-Item -ItemType Directory -Path $newfolderpath -ErrorAction "SilentlyContinue"
                $filepathtxt = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenametxt
                $filepathhtml = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenamehtml
                $description = "Hotfix"
                Write-Host "Gathering Information for $computername" -ForegroundColor green
                $hotfix = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description
                $hotfixtxt = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description | Out-File -FilePath $filepathtxt
                $hotfixhtml = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description | ConvertTo-Html -Property CSName,Description,HotFixID,InstalledBy,InstalledOn -Head $htmlstyle -Body "<H2>Installed $description on $computername</H2>" | out-file -FilePath $filepathhtml
                Write-host "The count of all installed Hotfixes on $computername is:" $hotfix.count
                $hotfix
                write-host ""
                Write-host "Files have been saved to" $newfolderpath
                Write-Host ""
                Write-Host "Sending Mail message to $recipeint" -ForegroundColor blue
                Send-MailMessage -to $recipeint -From $sender -Subject "Installed $description on $computername" -Body "Installed $description on $computername" -Attachments $filepathtxt,$filepathhtml -SmtpServer 172.21.195.31
                
            }
        }
    2 
        {
            foreach ($computername in $computernames)
            {
                $filenamehtml = "securityupdates.html"
                $filenametxt = "securityupdates.txt"
                $newfolderpath = $dir.tostring() + "\" +$date + "\" + $computername + "\"
                New-Item -ItemType Directory -Path $newfolderpath -ErrorAction "SilentlyContinue"
                $filepathtxt = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenametxt
                $filepathhtml = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenamehtml
                $description = "Security Update"
                Write-Host "Gathering Information for $computername" -ForegroundColor green
                $securityupdate = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description
                $securityupdatetxt = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description | Out-File -FilePath $filepathtxt
                $securityupdatehtml = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description | ConvertTo-Html -Property CSName,Description,HotFixID,InstalledBy,InstalledOn -Head $htmlstyle -Body "<H2>Installed $description on $computername</H2>" | out-file -FilePath $filepathhtml
                Write-host "The count of all installed Service Packs on $computername is:" $securityupdate.count
                $securityupdate
                write-host ""
                Write-host "Files have been saved to" $newfolderpath
                Write-Host ""
                Write-Host "Sending Mail message to $recipeint" -ForegroundColor blue
                Send-MailMessage -to $recipeint -From $sender -Subject "Installed $description on $computername" -Body "Installed $description on $computername" -Attachments $filepathtxt,$filepathhtml -SmtpServer 172.21.195.31
            }
        }
    3 
        {
            foreach ($computername in $computernames)
            {
                $filenamehtml = "updates.html"
                $filenametxt = "updates.txt"
                $newfolderpath = $dir.tostring() + "\" +$date + "\" + $computername + "\"
                New-Item -ItemType Directory -Path $newfolderpath -ErrorAction "SilentlyContinue"
                $filepathtxt = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenametxt
                $filepathhtml = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenamehtml
                $description = "Update"
                Write-Host "Gathering Information for $computername" -ForegroundColor green
                $update = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description
                $updatetxt = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description | Out-File -FilePath $filepathtxt
                $updatehtml = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description | ConvertTo-Html -Property CSName,Description,HotFixID,InstalledBy,InstalledOn -Head $htmlstyle -Body "<H2>Installed $description on $computername</H2>" | out-file -FilePath $filepathhtml
                Write-host "The count of all installed Service Packs on $computername is:" $update.count
                $update
                write-host ""
                Write-host "Files have been saved to" $newfolderpath
                Write-Host ""
                Write-Host "Sending Mail message to $recipeint" -ForegroundColor blue
                Send-MailMessage -to $recipeint -From $sender -Subject "Installed $description on $computername" -Body "Installed $description on $computername" -Attachments $filepathtxt,$filepathhtml -SmtpServer 172.21.195.31
            }
        }
    4 
        {
            foreach ($computername in $computernames)
            {
                $filenamehtml = "servicepack.html"
                $filenametxt = "servicepack.txt"
                $newfolderpath = $dir.tostring() + "\" +$date + "\" + $computername + "\"
                New-Item -ItemType Directory -Path $newfolderpath -ErrorAction "SilentlyContinue"
                $filepathtxt = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenametxt
                $filepathhtml = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenamehtml
                $description = "Service Pack"
                Write-Host "Gathering Information for $computername" -ForegroundColor green
                $servicepack = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description
                $servicepacktxt = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description | Out-File -FilePath $filepathtxt
                $servicepackhtml = Get-HotFix -ComputerName $computername -Description $description -Credential $cred | Sort-Object -Property Description | ConvertTo-Html -Property CSName,Description,HotFixID,InstalledBy,InstalledOn -Head $htmlstyle -Body "<H2>Installed $description on $computername</H2>" | out-file -FilePath $filepathhtml
                Write-host "The count of all installed Service Packs on $computername is:" $all.count
                $servicepack
                write-host ""
                Write-host "Files have been saved to" $newfolderpath
                Write-Host ""
                Write-Host "Sending Mail message to $recipeint" -ForegroundColor blue
                Send-MailMessage -to $recipeint -From $sender -Subject "Installed $description on $computername" -Body "Installed $description on $computername" -Attachments $filepathtxt,$filepathhtml -SmtpServer 172.21.195.31
            }
        }
    5 
        {
            foreach ($computername in $computernames)
            {
                $filenamehtml = "all.html"
                $filenametxt = "all.txt"
                $newfolderpath = $dir.tostring() + "\" +$date + "\" + $computername + "\"
                New-Item -ItemType Directory -Path $newfolderpath -ErrorAction "SilentlyContinue"
                $filepathtxt = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenametxt
                $filepathhtml = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenamehtml
                Write-Host "Gathering Information for $computername" -ForegroundColor green
                $all = Get-HotFix -ComputerName $computername -Credential $cred | Sort-Object -Property Description
                $alltxt = Get-HotFix -ComputerName $computername -Credential $cred | Sort-Object -Property Description | Out-File -FilePath $filepathtxt
                $allhtml = Get-HotFix -ComputerName $computername -Credential $cred | Sort-Object -Property Description | ConvertTo-Html -Property CSName,Description,HotFixID,InstalledBy,InstalledOn -Head $htmlstyle -Body "<H2>Installed $description on $computername</H2>" | out-file -FilePath $filepathhtml
                Write-host "The count of all installed hotfixes on $computername is:" $all.count
                $all
                write-host ""
                Write-host "Files have been saved to" $newfolderpath
                Write-Host ""
                Write-Host "Sending Mail message to $recipeint" -ForegroundColor blue
                Send-MailMessage -to $recipeint -From $sender -Subject "Installed $description on $computername" -Body "Installed $description on $computername" -Attachments $filepathtxt,$filepathhtml -SmtpServer 172.21.195.31 
            }
        }    
    default 
        {
            foreach ($computername in $computernames)
            {
                $filenamehtml = "all.html"
                $filenametxt = "all.txt"
                $newfolderpath = $dir.tostring() + "\" +$date + "\" + $computername + "\"
                New-Item -ItemType Directory -Path $newfolderpath -ErrorAction "SilentlyContinue"
                $filepathtxt = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenametxt
                $filepathhtml = $dir.tostring() + "\" +$date + "\" + $computername + "\" + $filenamehtml
                Write-host "Not a valid choice"
                Write-host "Assuming you want all updates"
                Write-Host "Gathering Information for $computername" -ForegroundColor green
                $all = Get-HotFix -ComputerName $computername -Credential $cred | Sort-Object -Property Description
                $alltxt = Get-HotFix -ComputerName $computername -Credential $cred | Sort-Object -Property Description | Out-File -FilePath $filepathtxt
                $allhtml = Get-HotFix -ComputerName $computername -Credential $cred | Sort-Object -Property Description | ConvertTo-Html -Property CSName,Description,HotFixID,InstalledBy,InstalledOn -Head $htmlstyle -Body "<H2>Installed $description on $computername</H2>" | out-file -FilePath $filepathhtml
                Write-host "The count of all installed hotfixes on $computername is:" $all.count
                $all
                write-host ""
                Write-host "Files have been saved to" $newfolderpath
                Write-Host "" 
                Write-Host "Sending Mail message to $recipeint" -ForegroundColor blue
                Send-MailMessage -to $recipeint -From $sender -Subject "Installed $description on $computername" -Body "Installed $description on $computername" -Attachments $filepathtxt,$filepathhtml -SmtpServer 172.21.195.31
            }
        }
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Hope you find this helpful.

Follow me

facebook-small32222 twitter-small32222