VMware Daily Health Check HTML Report PowerShell

I have been working on a daily check report for our VMware environment so that we don’t have to manually check each morning.

The report uses PowerCli to generate information and then output the results to a HTML file.

The report requires a few that either the old PowerCLI snapin is available or preferably the PowerCLi PowerShell module.

The script can either be run directly by a users with rights to query vCenter or by setting up a scheduled task.

The following prerequisite will be needed for the script to run.

  • PowerShell V4 or V 5
  • PowerCLI 6.0 or later version
  • vCenter 6.0 or later version

There will also need to be a mail server or relay server available for the report to be emailed.

This has been tested on PowerCLI version 6.0 and above. The version on the server I will be running from is 12.3.0 which is the latest release at this time.

The report checks

  • vCenter connection
  • VMware tools check
  • Snapshot older than the specified snapshots days
  • Host Alarms
  • VM Alarms
  • vCenter Alerts over the last 12 hours
  • Datastore under specified % free space

There are mandatory parameter that are required for the script to run and send the report.

  • VCServer = vCenter Server address
  • SMTPServer = Mail server address
  • Toaddress = destination email
  • Fromaddress = sending address
  • Report Export = folder report will be exported to

There are some variables at the start of the script that can be set to customize the report to only show the required snapshots days and datastore % free. In my case I wanted 3 days and below 20% free on datastores.

I have embedded the html CSS format in the script so it can be update to change the color, font size or font type.

Example of how to run the script is below



.\VMwareDailReportv1.ps1 -VCServer vcenter.domain.local  -SMTPServer mail.doamin.local -FromAddress VMwareReport@domain.local -toAddress Administrator@domain.local -ReportExport D:\Scripts\VMware\Daily_Report

Once completed the report should be emailed to the specified to address.

Below is an example of the report export.

The full script can be downloaded from.

Scripts/VMwareDailyReport.ps1 at master · TheSleepyAdmin/Scripts (github.com)

To create a scheduled task to run the report each morning go to scheduled task on the server or client that has PowerCLI installed.

Create a new task

Set the schedule.

Next we need to set PowerShell as the program to start and set the argument to similar to the below, updating the parameters and script location

-ExecutionPolicy Bypass -NoProfile -File D:\Scripts\VMware\Daily_Report\VMwareDailReportv1.ps1 -VCServer vcenter.domain.local -SMTPServer mail.doamin.local -FromAddress VMwareReport@domain.local -toAddress Administrator@domain.local -ReportExport D:\Scripts\VMware\Daily_Report

I don’t change anything on conditions tab and only update that stop task if running longer than an hour in the settings tab.

Once completed run the task to confirm all is working.

I will probable added to the script but this is just the initial version and thought it might be helpful to anyone who want to try automate some of there manual checks.

Windows 10 20H2 Feature Update Error 0XC190012E

During our recent Windows 10 feature update deployment from 1809 to 20H2, we ran in to an issue on some clients where they reported back error 0XC190012E to ConfigMgr.

The error code its self is just a generic code and I couldn’t find it in either

Windows update error code list

Windows Update error code list by component – Windows Deployment | Microsoft Docs

or the Windows 10 upgrade errors doc

Get help with Windows 10 upgrade and installation errors (microsoft.com)

We first checked the temporary location that feature update deploys to c:\$Windows.~BT, to check if there was any issue in the compatibility xml file or in the setup logs under sources\panther, but there was no folders other than sources.

Since there was no files I though this might be a space issue so ran some remote WMI commands to check the disk space available. I used the below PowerShell using Get-WMIObject.

Get-WmiObject Win32_logicaldisk -ComputerName RemoteComputerName | Select-Object @{Name="Drive";E={$_.DeviceID}},
@{Name="Size(GB)";E={[math]::Round($_.size/1gb)}},
@{Name="Free Space(GB)";E={[math]::Round($_.freespace/1gb)}},
@{Name="%Free Space";E={"{0:N2}" -f (($_.freespace/$_.size)*100)}}

In this case it wasn’t disk space a there was over 100GB free.

There wasn’t much online about the error other than the usually run scf /scannow, diskcheck and run the update troubleshooter but none of these worked.

Then found this post on the Microsoft forms that pointed to an issue with the setupconfig.ini

Generic 0xc190012e trying to upgrade Windows 10 1909 to 20H2 – Microsoft Community

C:\Users\Default\AppData\Local\Microsoft\Windows\WSUS

We aren’t using any custom setting in the setupconfig.ini so there was no issue for me to remove this.

Once I removed the file and kicked off the feature update again it now completes without issue.

I don’t know how the setupconfig.ini file was created on only a few devices but it was a quick fix once we found the issue was the config file.

Install and Configure vRealize Operations Manager 8.2 Part 8 Configure Windows Server Monitoring

In the previous seven post’s we went through installing and configuring the vROps virtual appliance, connecting to vCenter server, configuring Window Active directory as an identity source, create custom alerts and notifications, creating dashboards, upgrading the appliance to the latest version and requesting / configuring a custom SSL cert.

Part 1: Install and Configure vRealize Operations Manager 8.2 Part 1 – TheSleepyAdmins

Part 2: Install and Configure vRealize Operations Manager 8.2 Part 2 Connect to vCenter – TheSleepyAdmins

Part 3: Install and Configure vRealize Operations Manager 8.2 Part 3 AD Authentication – TheSleepyAdmins

Part 4: Install and Configure vRealize Operations Manager 8.2 Part 4 Create Alerts and Notifications – TheSleepyAdmins

Part 5: Install and Configure vRealize Operations Manager 8.2 Part 5 Create a Dashboard – TheSleepyAdmins

Part 6: Install and Configure vRealize Operations Manager 8.2 Part 6 Upgrading vROps – TheSleepyAdmins

Part 7: Install and Configure vRealize Operations Manager 8.2 Part 7 Configure Custom Certificate – TheSleepyAdmins

In this post we will be going through installing the Windows agent and configuring the management pack to alert on Windows server OS level alerts like performance, services and application. This can be useful for monitoring physical servers running Windows.

Below is a link to the VMware document on vROps agent deployment I used for reference.

End Point Operations Management Agent Installation and Deployment (vmware.com)

Below is the list of support Operating system for vROps agent.

Operating SystemProcessor ArchitectureJVM
RedHat Enterprise Linux (RHEL) 5.x, 6.x, 7.xx86_64, x86_32Oracle Java SE8
CentOS 5.x, 6.x, 7.xx86_64, x86_32Oracle Java SE8
SUSE Enterprise Linux (SLES) 11.x, 12.xx86_64Oracle Java SE8
Windows 2008 Server, 2008 Server R2x86_64, x86_32Oracle Java SE8
Windows 2012 Server, 2012 Server R2x86_64Oracle Java SE8
Windows Server 2016x86_64Oracle Java SE8
Solaris 10, 11x86_64, SPARCOracle Java SE7
AIX 6.1, 7.1Power PCIBM Java SE7
VMware Photon Linux 1. 0x86_64Open JDK 1.8.0_72-BLFS
Oracle Linux versions 5, 6, 7x86_64, x86_32Open JDK Runtime Environment 1.7

First we need to enabled the management pack for Operating Systems / Remote Services Monitoring.

After the management pack is enabled we need to download the agent, the 8.2 version works for both 8.2 and 8.3 and is available to download on the same page as the vROps appliance.

Download vRealize Operations – My VMware

Once we have the agent, we can deploy to the servers that need to be monitored.

Copy the file to the server and run installer.

Add in the vROps server when prompted to

Next the installer will look for the thumbprint for the cert that is used for vROps. Logon to https://vrops/admin and click on the cert icon on the top right to view the current cert details.

Enter the user name and password that will be used to connect to vROps.

Set the install location the default is to install in c:\ep-agent this can be change if required.

The agent should now start to install.

We can run ep-agent.bat query from the install folder ep-agent\bin to confirm the agent has installed correctly.

Once completed we can check vROps to confirm the agent is reporting back, to view the agent in vROps logon to the web client > Administration > End Point Operations.

To view details for the server go to Environment > Operating Systems > Operating System World > Windows and select the server to view.

Once the server is added we can now monitor disk, CPU, memory and other metrics.

We can also monitor services.

To add a service to be monitored,

Go to server and click on action > monitor os object > monitor windows service

Give the monitor a name, select the object type and add in the service name (this needs to be the actual name and not the display name)

This image has an empty alt attribute; its file name is image-22.png

Set the collection interval. Click ok to to create the monitor.

Click on Environment and we can view the service monitor we just added.

If we stop the service the next time the collection runs the service should show a critical alert.

We can add addtional metrics if needed. In this example we might want to see the logical disk space % free.

First we either need to modify the existing policy or create a new policy.

In this example we will be adding a new policy and inherting from the default policy.

Go to Policies and click add, give the policy a name and select where it will be inherit from. Then click create policy.

Go to the policies and click on the policy we just created and go to edit policy.

We will be adding a metric so we will select metrics and properties and enable the required metrics.

% free is under EP Ops Adapter > Windows >Fileserver Logical Disk > Utilization and % Free space (%).

Set the policy state to enabled.

Next we can apply the policy to either the object or if there are a lot of device it would be easier to create and apply to a custom group.

Now we can go to the server and confirm the policy is applied.

After a few minutes we can check the server object we can see the new metric and the data start to be shown.

Now that we have the metric showing next we can create an alert.

First we will need to create a symptom definition. Go to symptom definitions and click add.

Select the metric that will be used and give the symptom a name and set the threshold.

We can search to for the symptom to confirm it exist.

Next we need to create the alert. Go to alert definitions and click add.

Give the Alert a name and select Windows as the base object type.

Next we need to add the symptom we created.

Add a recommendation if any are applicable or create a recommendation (this is not required but can be usefully)

We need to add to a policy in this case it’s the Windows_Server_Agent and create a notification if this is required.

This image has an empty alt attribute; its file name is image-48.png

We can search for the alert to confirm it has been created and to view the details.

Now when the server goes below 10% free disk space the server will alert.

Below is what the email notification will look like, we have configured email notification in a previous post so we wont go back over it here.

There are many metrics and alerts that can be configure this is just an example of one type. We can also create multiple alerts so that we get warning alerts at maybe 20% before getting a critical alert.

Install and Configure vRealize Operations Manager 8.2 Part 7 Configure Custom Certificate

In the previous six post’s we went through installing and configuring the vROps virtual appliance, connecting to vCenter server, configuring Window Active directory as an identity source, create custom alerts and notifications, creating dashboards and upgrading the appliance to the latest version.

Part 1: Install and Configure vRealize Operations Manager 8.2 Part 1 – TheSleepyAdmins

Part 2: Install and Configure vRealize Operations Manager 8.2 Part 2 Connect to vCenter – TheSleepyAdmins

Part 3: Install and Configure vRealize Operations Manager 8.2 Part 3 AD Authentication – TheSleepyAdmins

Part 4: Install and Configure vRealize Operations Manager 8.2 Part 4 Create Alerts and Notifications – TheSleepyAdmins

Part 5: Install and Configure vRealize Operations Manager 8.2 Part 5 Create a Dashboard – TheSleepyAdmins

Part 6: Install and Configure vRealize Operations Manager 8.2 Part 6 Upgrading vROps – TheSleepyAdmins

In this post we will be going through requesting and applying a custom certificate. Configuring a custom cert is good practice from security standpoint and also will stop the security warning when access the vRealize web client.

Adding a certificate requires that there is a internal certificate authority that can be used to issue the certificate or we could use a public CA but there would be a cost to that, in this example we will be using a Windows Server CA.

I used the below VMware kb as reference when creating the cert.

Enabling TLS on Localhost Connections (vmware.com)

Configure a Custom Certificate (vmware.com)

First step is to connect to the vROps appliance using ssh connection and to generate the key file and cert request that will be used to generate the cert.

To enabled ssh go to the admin page and enable the ssh status.

If you have not updated the root password on the appliance already then this require to connect by ssh. To do this open a VM console for the appliance and go to login. The default root password is blank so just hit enter and it will prompt for a new password to be set.

Once the above has been completed, ssh to the vrops server I use putty but any ssh client will work.

After connecting I usually create a folder to keep the key file and cert request to they are simpler to find later if I need them again.

Next we need to generate a key file

openssl genrsa -out key_filename.key 2048

Next run the below command to create the certificate request

openssl req -new -key key_filename.key -out certificate_request.csr

Enter in the details for the cert. These can also be pre creating using a .config file but I just typed them in to the ssh console.

There should now be a key file and cert request in the folder.

Copy the .csr file as this will be used to generate the cert from the internal CA.

To generate the certificate logon on to the Microsoft CA web enrollment page.

Click submit and advanced certificate request.

Click submit a certificate request

Open the .csr file in a text editor and copy the content to certificate request box and select the certificate template to be used.

Click submit and the certificate should be generated. The cert needs to be downloaded as base 64.

Save the cert. The root CA cert also needs to be downloaded

Once all the cert files and key file are created, they now need to be combined to a .PEM format as that is the required format for vrops.

To combine the cert using Windows using the type command. The order the of the cert needs to be server cert, then key file, intermediate cert (if there are any in my case I only have the root cert) , root cert and then the PEM output.

type server_cert.cer key_filename.key cacerts.cer > vrops.pem

The .PEM file should now be created and is ready to be applied to vROps.

The last step is to apply the certificate, logon to the vROps admin page and go to the certificate icon in the top right.

Click Install new certificate.

Click browse and select the pem file we created. If there are no issue with verifying the pem file it should show as ready to install.

Click install to complete. The page should now reload and when we check the cert it should now be using the custom cert.

In the next post we will go through installing the Windows vROps agent and configuring the Windows management pack.

Install and Configure vRealize Operations Manager 8.2 Part 6 Upgrading vROps

In the previous five post’s we went through installing and configuring the vROps virtual appliance, connecting to vCenter server, configuring Window Active directory as an identity source, create custom alerts and notifications and creating dashboards.

Part 1: Install and Configure vRealize Operations Manager 8.2 Part 1 – TheSleepyAdmins

Part 2: Install and Configure vRealize Operations Manager 8.2 Part 2 Connect to vCenter – TheSleepyAdmins

Part 3: Install and Configure vRealize Operations Manager 8.2 Part 3 AD Authentication – TheSleepyAdmins

Part 4: Install and Configure vRealize Operations Manager 8.2 Part 4 Create Alerts and Notifications – TheSleepyAdmins

Part 5: Install and Configure vRealize Operations Manager 8.2 Part 5 Create a Dashboard – TheSleepyAdmins

In this post we will be going through upgrading the vROps appliance to the latest version 8.3. Keeping appliances up to date is good from a security standpoint and also allows for new features and fixes to be applied.

To confirm if the upgraded version of vROps is supported by the existing vCenter version use the VMware interoperability matrix site.

Product Interoperability Matrix (vmware.com)

Once this has been confirmed as supported we will need to download the .pak file that will be used to update the appliance.

To download go the following URL

https://my.vmware.com/en/group/vmware/downloads/info/slug/infrastructure_operations_management/vmware_vrealize_operations/8_3

Select the version and edition required in my case it Enterprise

Select upgrade type we will be upgrading from 8.2 so we will use 8.x, there is also a upgrade assessment tool that can be run to do a pre check.

Once the .pak files has been downloaded we are ready to start the upgrade. We will run the assessment first and view the report then process with the full upgrade.

To access the admin page use /admin at the end of the vROps URl. We can check the current version on the system status page.

https://vropsserver/admin

Go to software update and click install a software update.

Click browse and select the .pak file and click upload

Once the file is uploaded click next

Accept the end user agreement.

Next you can review the update info and the last screen is to install.

The installation should now start, it took about 10 minute to complete.

This image has an empty alt attribute; its file name is image-89.png

Once the assessment is completed, we need to go to the support tab and select support bundles. Click on the download icon to download the zip file.

To view the report click the download and extract the zip file go to \apuat-data\report and click on the index.html.

This image has an empty alt attribute; its file name is image-91.png

If there are no issue reported in the pre assessment we can go ahead with the upgrade.

It is recommend to take a backup of the appliance before upgrading in case there are any issue during the install.

First part of the upgrade is to take the cluster offline, go to the system status page

Once the cluster is offline we can uploaded and apply the .pak file similar to the assessment tool.

Go to software update > Install a software update, select the upgrade pak file and upload.

Follow the wizard to start the upgrade.

The upgrade took 30 minutes to complete and the cluster to come back online. Once fully back online we can confirm that the version is now upgraded to 8.3.

In the next post we will go thorough configuring a custom SSL cert to replace the self singed cert to give better security.

Manage Calendar Permissions in Office 365 PowerShell

I had been asked to update all users calendar permission to allow a certain application to be able to edit users calendar so it can automate adding days off and other calendar items.

Currently the only way this can be done that I know off is either using PowerShell or using MS Graph.

In this post we will be going through how to report calendar permission for all users and how to bulk update. We will be using the exchange online PowerShell module.

https://docs.microsoft.com/en-us/powershell/exchange/exchange-online-powershell-v2?view=exchange-ps#install-the-exo-v2-module

Install-Module -Name ExchangeOnlineManagement

To get the list of mailboxes and permissions we will use two command Get-Mailbox and Get-MailboxFolderPermission. Then we will be formatting the results for export out to a CSV.

To get calendar permission we will need to add :\Calendar to after the UserPrincipalName.

First step is that we need to connect to Exchange Online using PowerShell.

Connect-ExchangeOnline

To get a single user’s permission use

Get-MailboxFolderPermission -Identity user@domain.com:\calendar 

To check for a specific users permission we can add the -user parameter.

To get all users permission we need to get a list of all users using Get-Mailbox and then loop through each user to get the permission.

## Get all users mailboxes
$Mailboxes = Get-Mailbox -ResultSize Unlimited | Select-Object UserPrincipalName

## Loop through each mailbox
foreach ($mailbox in $Mailboxes) {

## Get default user calendar permissions
Write-Warning "Checking Permission on $($mailbox.UserPrincipalName)"
Get-MailboxFolderPermission -Identity "$($mailbox.UserPrincipalName):\Calendar" | 
Select-Object @{Name="UserPrincipalName";E={$mailbox.UserPrincipalName}},FolderName,User,AccessRights |
Export-Csv C:\temp\Office_365_Export\Calendar_Report\CalenarPermissionReport.csv -NoTypeInformation -Append
}

The export should look like the below.

Once I had a report of the current users calendar permission, I needed to add the user account that the application would use to add the calendar items.

To add calendar permission we use the Add-MailboxFolderPermission,

The roles that are available, along with the permissions that they assign are below.

  • Author: CreateItems, DeleteOwnedItems, EditOwnedItems, FolderVisible, ReadItems
  • Contributor: CreateItems, FolderVisible
  • Editor: CreateItems, DeleteAllItems, DeleteOwnedItems, EditAllItems, EditOwnedItems, FolderVisible, ReadItems
  • None: FolderVisible
  • NonEditingAuthor: CreateItems, FolderVisible, ReadItems
  • Owner: CreateItems, CreateSubfolders, DeleteAllItems, DeleteOwnedItems, EditAllItems, EditOwnedItems, FolderContact, FolderOwner, FolderVisible, ReadItems
  • PublishingEditor: CreateItems, CreateSubfolders, DeleteAllItems, DeleteOwnedItems, EditAllItems, EditOwnedItems, FolderVisible, ReadItems
  • PublishingAuthor: CreateItems, CreateSubfolders, DeleteOwnedItems, EditOwnedItems, FolderVisible, ReadItems
  • Reviewer: FolderVisible, ReadItems

To add a single user use the command below.

Add-MailboxFolderPermission -Identity user@domain.com:\calendar -User "Account to be added" -AccessRights Editor 

I also wanted to be able to run this script again and not have to modify users that already have the correct permission as this will return an error, so we will be using a if statement to only apply to users who don’t have the permission.

Below is the full script.

## Calendar Permission Variable
$Account = "Account to be added"
## Get all users mailboxes
$Mailboxes = Get-Mailbox -ResultSize Unlimited | Select-Object UserPrincipalName

## Loop through each mailbox
foreach ($mailbox in $Mailboxes) {

## Get default user calendar permissions
$permission = Get-MailboxFolderPermission -Identity "$($mailbox.UserPrincipalName):\Calendar"

## Report on Users without correct calendar permissions and set permissions
if ($permission.User.DisplayName  -notcontains $Account) {
Write-Warning "Calender permission not set on $($mailbox.UserPrincipalName) adding Permission"
Add-MailboxFolderPermission -Identity "$($mailbox.UserPrincipalName):\Calendar" -User $Account -AccessRights Editor | Out-Null
} 

## calendar permission are correct
else {Write-Host "Calender Permission are set on $($mailbox.UserPrincipalName)" -ForegroundColor Green}

}

Install and Configure vRealize Operations Manager 8.2 Part 5 Create a Dashboard

In the previous four post’s we went through installing and configuring the vROps virtual appliance, connecting to vCenter server, configuring Window Active directory as an identity source and create custom alerts and notifications.

Part 1: Install and Configure vRealize Operations Manager 8.2 Part 1 – TheSleepyAdmins

Part 2: Install and Configure vRealize Operations Manager 8.2 Part 2 Connect to vCenter – TheSleepyAdmins

Part 3: Install and Configure vRealize Operations Manager 8.2 Part 3 AD Authentication – TheSleepyAdmins

Part 4: Install and Configure vRealize Operations Manager 8.2 Part 4 Create Alerts and Notifications – TheSleepyAdmins

In this post we will be creating a custom dashboard. Dashboard can be used to visual your VMware infrastructure, view performance issue and capacity planning / right sizing. Dashboards are made up of views and widgets.

We can create custom dashboards or clone and existing dashboard and modify that to add addtional view or widgets.

To create a new dashboard logon to the vROps web client > Dashboards > Dashboards > Create Dashboard

Give the dashboard a name and we can toggle between view and widgets using the below button.

Start adding the required views / widgets for the dashboard in this dashboard we are looking for performance related.

First we will add a view list that we will use to create an relationship with the other widgets.

Give the view a name and select if the content should be refreshed or not. Since I want to specify the cluster I will be setting self provider to On. If this is not set to on input data object will be greyed out

Next we need to specify the object under the inventory tree. We will be using vSphere Host and Clusters and the object will be vSphere World.

Under output data we will use cluster utilization.

Click save and output should look like the below.

Once we have the view we can add the addtional widgets and start creating the interactions.

No data will be showing till the Interactions are in place.

After adding in the required widgets and click on show interactions.

Now we just connect the LAB_Cluster view to the other widgets we just added.

Now if we select the cluster view we will have alert volume, health data, scoreboard and object relationship information returned.

If we want to share the dashboard with other users we can select share icon

Click on groups and select the group to be included.

Now share icon should show beside the name of the dashboard.

If there are pre existing dashboard that we want to customize we can clone these by going to Dashboards >> Manage Dashboards, select the dashboard you want to clone, click on the three dots and select clone.

Give the dashboard a name and we can then start to modify.

In the next post we will go through scheduling reports and updating vROps appliance

Install and Configure vRealize Operations Manager 8.2 Part 4 Create Alerts and Notifications

In the previous three post we went through installing and configuring the vROPs virtual appliance, connecting to vCenter server and configuring Window Active directory as an identity source.

Part 1: Install and Configure vRealize Operations Manager 8.2 Part 1 – TheSleepyAdmins

Part 2: Install and Configure vRealize Operations Manager 8.2 Part 2 Connect to vCenter – TheSleepyAdmins

Part 3: Install and Configure vRealize Operations Manager 8.2 Part 3 AD Authentication – TheSleepyAdmins

In this post we will be going through the different alert types and configuring actions bases on certain alerts.

Alerts:

Below are the three types of alert in vROPs:
Health Alerts:
The health alert list is all the generated alerts that are configured to affect the health of your
environment and require immediate attention. You use the health alert list to evaluate,
prioritize, and immediately begin resolving the problems.


Risk Alerts:
The risk alerts list is all the generated alerts that are configured to indicate risk in your
environment. Address risk alerts in the near future, before the triggering symptoms that
generated the alert negatively affect the health of your environment.


Efficiency Alerts:
The efficiency alerts list is all the generated alerts that are configured to indicate problems
with the efficient use of your monitored objects in your environment. Address efficiency
alerts to reclaim wasted space or to improve the performance of objects in your environment.

Each alert type has four different severity types, info, warning, immediate and critical. The can all be configured

To create a custom alert logon to vROPs web client > alerts > Alert Definitions

Click Add, give the alert a name

We will be using virtual machine so we will

select base object type and select vCenter Adapter > virtual Machine

We want to alert on Capacity so click on advanced.

Impact = Health

Criticality = Symptom based

Alert Type & Subtype = Virtualization/Hypervisor : Capacity

Next we need to add the a symptom that will be used to trigger the alert. If there is no symptom that matches what we want to alert on we can create a new symptom. For snapshot there is only greater than 2 days so we will create a new symptom.

We will be using Virtual Machine: Disk space > Snapshot > Age (Days) and set the value to greater than 5 days.

We can set a recommendation that already exists to not keep snapshots over 72 hours or create a custom recommendation.

We can also apply a policy we will use the default policy.

Complete the wizard to create the new alert.

Next we will configure an email notification instance to allow alerts to be emailed.

Go to Administration > Outbound Settings > Add

Added in the email servers settings.

Click test to validate the mail flow is working.

Click save to to complete.

Once we have the outbound email instance configured, we can setup alerts to send emails notifications.

I created a new alert for Powered off VM so it would be easier to get a alert to trigger to test the email notification.

Go to Alerts > Notification

Next add in the details and select the email instance we setup earlier. I will be alerting for when LAB-Linux01 is powered off so will use object and specify the VM name and alert definition.

Click save to create the notification.

Now once the VM is powered off we will get an notification.

In the next post we will be going through creating a dashboard.

Microsoft Graph Filtering Results PowerShell

During a recent audit we have been trying to automate a report on what Guest account’s are active in the last 30 days and to find what groups these guest account are members of so they can be removed if they are no longer required.

We could use AzureAD PowerShell for getting guest account and group membership but it was not that easy to automate this.

We decided to use Microsoft Graph as we have a few task already automated using Microsoft Graph and certificates so there is no need to hard code any password or application secret in my script.

I have done a previous post on the getting the access token and using certificate based authentication so if you need to know how to setup you can check that post.

Connect to Microsoft Graph using MSAL and Certificate based Authentication – TheSleepyAdmins

In this query we will be using three different Microsoft Graph url’s. First is to get a list of guest users, second will be to get sign-in logs and the last will be to get the guest users group membership.

To get guest users we will filtering using userType attribute

user resource type – Microsoft Graph v1.0 | Microsoft Docs

below are the permission that will be required

ApplicationUser.Read.All, User.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All

To get sign-in’s we will be filtering on two different attributes (userPrincipalName & createdDateTime)

List signIns – Microsoft Graph v1.0 | Microsoft Docs

below are the permission that will be required

ApplicationAuditLog.Read.All and Directory.Read.All

To get Group membership we will be using the memberof

user: getMemberGroups – Microsoft Graph v1.0 | Microsoft Docs

below are the permission that will be required for getting the group membership.

ApplicationUser.Read.All, Directory.Read.All, Directory.ReadWrite.All

First step as with any Graph query is to create the token request that will be used to access the different Graph Url’s. We will be using MSAL module and a certificate to generate.

To filer results using Graph we can put in ?filter= and then use a supported filter attribute. In this case we will be using usertype.

We will also create a blank array variable that will be used to output to later and a date variable to filer the sign-in logs.

This first filter will get all guest users. Currently usertype is only available when using the beta Graph version so we will be using that.

"https://graph.microsoft.com/beta/users/?filter=usertype eq 'Guest'"

Once we have the Guest users we will loop through each one, use a second filter that uses the mail address to filter the guest user sign-in logs and use a date variable to show only sign-in over the last 30 days.

"https://graph.microsoft.com/beta/auditLogs/signIns/?filter=userPrincipalName eq '$($User.mail)' and createdDateTime ge $Date"

The next filter is going to use the user ID to get the memberof for the user and we will use the group-object to put all groups display names in to one object so it easier to call to the console windows or export to a CSV.

"https://graph.microsoft.com/beta/users/$($User.ID)/memberof"

Once we have all the information returned from the Graph queries we need to format the results. For this we will use a hash table and an if statement to output user with or without sign-in logs to the correct hash table and add the values to the results variable.

This script is only going to return the latest sign-in log as I only really want to have a report that the users has been active in the last 30 day that’s why I am using [0] to select the latest object in the $logins variable.

The last part of the script just outputs the results and use select-object to format the order.

Now that we have the full script the below is what the result should look like.

To make the script more reusable there are three variable for TenantId , ClientId and CertThumprint.

To export the result to a csv instead of the console windows there is an -Exportpath parameter that just needs to have the path specified.

The full script can be download from my Github repository

Scripts/MSGraph/GuestUserAuditReport at master · TheSleepyAdmin/Scripts (github.com)

To filter on other attributes we can use the same process as above just change the Graph url and check the document for that url to view what is a valid filter attribute. Filtering results in the the Graph url speeds up the script and mean we don’t do addtional filtering after returning all data.

Connect to Microsoft Graph using MSAL and Certificate based Authentication

I had a recently gotten some question’s on how to connect to Microsoft GraphApi using certificate instead of an app secret. I have set this up before using the Microsoft Graph PowerShell SDK but I wanted to test this using Invoke-RestMethod.

There is a PowerShell module that has been created that allow for much easier creation of authentication tokens using Microsoft Authentication Library.

Learn about MSAL – Microsoft identity platform | Microsoft Docs

The Microsoft Authentication Library (MSAL) enables developers to acquire tokens from the Microsoft identity platform in order to authenticate users and access secured web APIs. It can be used to provide secure access to Microsoft Graph, other Microsoft APIs, third-party web APIs, or your own web API. MSAL supports many different application architectures and platforms including .NET, JavaScript, Java, Python, Android, and iOS.

MSAL gives you many ways to get tokens, with a consistent API for a number of platforms. Using MSAL provides the following benefits:

  • No need to directly use the OAuth libraries or code against the protocol in your application.
  • Acquires tokens on behalf of a user or on behalf of an application (when applicable to the platform).
  • Maintains a token cache and refreshes tokens for you when they are close to expire. You don’t need to handle token expiration on your own.
  • Helps you specify which audience you want your application to sign in (your org, several orgs, work, and school and Microsoft personal accounts, social identities with Azure AD B2C, users in sovereign, and national clouds).
  • Helps you set up your application from configuration files.
  • Helps you troubleshoot your app by exposing actionable exceptions, logging, and telemetry.

The PowerShell module that can be used to create tokens is called MSAL.PS and the latest version as of today is 4.21.0.1.

PowerShell Gallery | MSAL.PS 4.21.0.1

In this post we will be going through installing and using this module to generate an authentication token using a self signed certificate and using that token to connect to Microsoft Gaph.

The first step is to install the MSAL.PS module

Once the module is installed we can generate the certificate that will be used to connect to Microsoft Graph

To create the self signed cert I used the below command. There was a error when trying to generated the token when I didn’t use -KeySpec when generating the cert. The fix to use -KeySpec was on the GitHub issue page.

Get-MsalToken with Client Certificate fails on Windows PowerShell 5.1 · Issue #15 · AzureAD/MSAL.PS (github.com)

New-SelfSignedCertificate -DnsName TennatDomainName -CertStoreLocation "Cert:\CurrentUser\My" -FriendlyName "MSAL_Cert" -KeySpec Signature

Once the cert has been created, export the cert so that it can be uploaded to the App registration.

Get-ChildItem Cert:\CurrentUser\my\CertThumbprint | Export-Certificate -FilePath C:\temp\Graph_MSAL_Cert.cer

Once the cert is exported we can upload to the app registration that we created before. See previous post if app registration hasn’t been created in Azure yet for Microsoft Graph.

Connecting to Microsoft GraphAPI Using PowerShell – TheSleepyAdmins

To add the cert open the Azure portal > Azure Active Directory >  App registrations and select the Graph app and go to certificates & secrets

Select upload certificate

Click add to apply the cert

After the cert is upload we should now be able to connect. We will need the TenantId, clientId and certificate

The tenantID and ClientId can be gotten from the app registration overview page and the cert can be gotten using Get-Item and the cert location / thumbprint.

Import-Module MSAL.PS
$TenantId = "TenantId"
$ClientId = "ClientId" 
$ClientCert = Get-ChildItem "Cert:\CurrentUser\my\CertThumbprint"
$MSToken = Get-MsalToken -ClientId $ClientId -TenantId $TenantId -ClientCertificate $ClientCert

If you want to use the same cert for any users on the device we can export and import the cert under localmachine cert store with the private key and update the $clientCert to use localmachine instead of currentuser.

Get-Item "Cert:\localmachine\my\CertThumbprint"

Once we have the token, it’s now the same process as we have used before to connect using invoke-restmethod but using the $MSToken.AccessToken we generated using the Get-MsalToken and our certificate.

$GraphGroupUrl = 'https://graph.microsoft.com/v1.0/Groups/'
(Invoke-RestMethod -Headers @{Authorization = "Bearer $($MSToken.AccessToken)"} -Uri $GraphGroupUrl -Method Get).value.displayName

Using MSAL.PS module provides a much quicker and easier way to generate access tokens for Microsoft Graph with the added security of using a certificate over having to put in any application secret.