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.

Install and Configure vRealize Operations Manager 8.2 Part 3 AD Authentication

In the previous post in this series we went through installing vROps virtual appliance and connecting to vCenter. In this post we will go through adding an AD authentication source and configuring access groups.

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

There are 5 different authentication sources that can be added to vROps.

  • SSO SAML: An XML-based standard for a web browser single sign-on that enables users to perform single sign-on to multiple applications.
  • VMware Identity Manager: A platform where you can manage users and groups, manage resources and user authentication, and access policies and entitle users to resources.
  • Open LDAP: A platform-independent protocol that provides access to an LDAP database on another machine to import user accounts.
  • Active Directory: Specifies the use on Active directory to be used to import users accounts or groups.
  • Other: Specifies any other LDAP-based directory services, such as Novel or OpenDJ, used to import user accounts from an LDAP database on a Linux Mac machine.

First we need to logon to the vROps web client > Administration > Authentication Sources

Click Add and select the source type required. We use Microsoft AD so we will be using Active Directory.

Give the identity source a display name I usually use the domain name as this make it simpler when view settings. Use basic as this auto-discovers the DC and DN (Distinguished Name).

Add the user account that will be used to for the LDAP connections to the domain. This account should only need to have domain users rights.

I also always create a specific service account to be uses for each application AD integration. I would also recommend using SSL/TLS where possible as this will encrypt the LDAP requests between the appliance and the domain controller.

Click on details to view the auto discovered host and

Click test verify all settings are correct, if set to use SSL there will be a prompt to accept the certificate.

Once the test is successful we can complete adding the authentication source.

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

Once completed the AD source should show.

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

Next we will configure the groups in AD that will be used to assign access roles in vROps.

To add the groups they need to be imported from AD and then assign the required role.

Go to Administrator > Access Control > import

Use the search string to check for the groups.

Select the role that will be assigned to the group

Assign the other required roles and select the object that are required for the group.

To test we can open a new session and select the AD authentication source instead of local user.

We there should also be logon events on the domain controller.

Based on the roles assinged the user will only have limited access.

In the next post we will go through configure alerting and create some capacity planning reports that can be used to plan for future compute requirements.

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

In part one of the blog series on installing and configuring vROps we deployed the virtual appliance. In this post we will be adding our vCenter server to vRops.

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

There are a few different types of accounts that can be added.

  • vCenter
  • VMC
  • AWS
  • Microsoft Azure

To add vCenter we need to logon to the vROps web client and go to Administration > Cloud Accoutns > Add Account

Select the account type for vCenter

Give the cloud Account a name, description and the vCenter DNS address and a logon credentials.

Click the validate connect to confirm the details are correct. If the certificate is not trusted you will be asked to review and confirm the certificate.

Once successfully completed we can then added vCenter.

The connection will now be setup and once completed will show under cloud accounts.

To view if information on the vCenter server is being collected we can go to Environment > vSphere Hosts and Clusters > vSphere World.

vROps can take a little time before metrics and alert start to show.

In the next post we will go through configuring AD Authentication and configuring group based access control.

Install and Configure vRealize Operations Manager 8.2 Part 1

In the next set of post’s we will be going through installing and configure vRealize Operations manager (vROps). I haven’t had to install or configure vROps in a few years so want to go back over it before we replaced our existing deployment.

vROps is a application from VMware that can be used to monitor, optimize and manage VMware management tools like vCentre, ESXi..

There are 3 different editions of vROps.

Standard: Allows management of vSphere only.

Advanced: Adding VMware cloud (AWS / Azure), Operating system monitoring and dashboards.

Enterprise: Give all the advanced features but also allows for application / database monitoring and third party management packs.

vROps Editions: Series Overview – VMware Cloud Management

We will be using Enterpirse edition.

vRops can be used for performance monitoring, over or under provisioned VM’s, capacity planning and trend analysis.

In this post we will be going through the initial virtual appliance deployment.

First step is to check what size appliance is going to be required.

We can use the sizing guidelines to select the right appliance size for the environment.

vRealize Operations 8.2 Sizing Guidelines (80893) (vmware.com)

Or use the VMware sizing tool

vRealize Sizing Tool (vmware.com)

Select the version you are installing and then add in the number of vCenter, host, datastores and VM that will have data collected and this will then give you the recommended sizing for your vROps deployment.

In my case it was extra small deployment.

What I always do before deploying any VMware appliance is create a static DNS record. This makes it easier to connect to the appliance after it’s deployed and for some appliance (like vCenter server its a requirement or the deployment will fail.)

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

To download the required vROps appliance go to my VMware and select the required version.

Download VMware vSphere – My VMware

To deploy the OVA create a new VM in VMware and select deploy VM from OVF or OVA file.

Give the appliance a Name and either drag and drop the OVA file or browse to the location and select.

Select a datastore

Agree to the end user license agreement.

Select a network, deployment type size, disk provisioning (thin or thick) and if VMware will be powered on automatically. Since this is only a single vCenter setup we will be using a small deployment type.

Set the timezone and network IP, gateway, netmask and domain name

Review the settings and complete.

The VM will start to deploy.

Once the deployment is completed, connect to either the IP or FQDN of the appliance to start the setup.

Select either express or new installation. We will be using the express installation as we only have one vCenter.

Set the admin password.

Complete the install

When the deployment completed the vROps logon page should show.

Logon and completed the installation.

Accept the End user agreement.

Enter your product key or use the evaluation.

You can join customer experience or untick to not take part.

Click finish to complete.

vROps is now installed.

In the next post we will go through connecting to vCenter Server, configure Active directory integration and build out some dashboards.

Checking LAPS Password Cross-Forest Using PowerShell

We have been using LAPS for the last year or so and for the most part it is a great tool for managing local admins password.

In our environment we have multiple forest with trusts relationships and the one main issue that we have is that the LAPS UI client can’t check the local admin password of devices in other domains, unless we logon as a user in that domain and run the LAPS UI as that user.

We can use PowerShell but this requires either the commands to be run from a devices in the domain with the LAPS PowerShell module or can be done using remote ps session but this is not something everyone on the service desk would know how to do or will have rights to do.

Enter-PSSession dc.domain.local
Get-AdmPwdPassword -ComputerName "computer" | Select-Object Password,ExpirationTimestamp

We could also get the AD attributes by using get-adcomputer comandlet but this requires the AD PowerShell module.

Get-ADComputer -Identity "computer" -Server "DC" -properties ms-mcs-admpwd,ms-mcs-admpwdexpirationtime | select-object ms-mcs-admpwd,ms-mcs-admpwdexpirationtime

I wanted to try create a script that would allow them to check the other domains without the needing to know how to do PS remoting or having modules installed.

To get around using the AD module we will be using ADSI search instead as this a default part of PowerShell. I used the below blog to get started.

Use the PowerShell [adsiSearcher] Type Accelerator to Search Active Directory | Scripting Blog (microsoft.com)

Hey, Scripting Guy! How Can I Search Active Directory from Within Windows PowerShell? | Scripting Blog (microsoft.com)

To query the remote doamin using adsisearch we first need to have a way of converting the domain name to the format that adsisearch requires.

This can be done using DirectoryContect class

System.DirectoryServices.ActiveDirectory.DirectoryContext

System.DirectoryServices.ActiveDirectory.Domain

DirectoryContext Class (System.DirectoryServices.ActiveDirectory) | Microsoft Docs

The first part of the script gets the domain details and returns the objects back to the search variable.

Next part we will filter the results based on the client variable to return only the required computer details.

Once the script is working, I just needed to create some mandatory parameters and create a function called Check-LAPS so that it’s easier for people to use without having to hardcode anything in the script and has some help and examples.

Below is the link to the full script.

Scripts/ActiveDirectory/LAPS at master · TheSleepyAdmin/Scripts (github.com)

Below shows how the script is run and the results.

I used the above script with WPF to create a GUI that is now complied in to an exe. I though this would be a lot easier to pass on the service desk as all they need to do is run the exe.

This was compiled using ps2exe PowerShell module.

MScholtes/PS2EXE: Module to compile powershell scripts to executables (github.com)

All they need to do is put in the domain name and computer name.

This should then return the LAPS password.

I will do a different post on creating the GUI itself in as this was my first GUI and I would like to create a few other.

Exchange Online PowerShell Basic Authentication Connection Issue

Today I ran in to an issue where I couldn’t connect to Exchange Online PowerShell. I could connect to other service without issue (Office 365, Azure AD….).

When trying to connect to Exchange online I was getting an warning about basic auth.

At first I thought this was to do with Microsoft deprecating basic authentication

Exchange Online deprecating Basic Authentication – Microsoft Lifecycle | Microsoft Docs

but after reading the document it says that this doesn’t affect Exchange ActiveSync (EAS), IMAP, POP, and Remote PowerShell.

I then read the Exchange Online v2 module prerequisites

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

In this there is a part that winrm needs to be enabled for basic authentication even though the module uses modern authentication.

This had been working for a long time without issue so I didn’t know what exactly had changed so I decided to check the winrm config

To check the winrm configuration run the below command

winrm get winrm/config/client/auth

In my case it was being set by a GPO. We had recently applied the Windows 10 2004 baseline policy to all our Windows 10 devices so I decided to check the setting in that GPO.

Security baseline (FINAL): Windows 10 and Windows Server, version 2004 – Microsoft Tech Community

There is a spreadsheet in the document folder that has all the policy settings. In the computer policy we can see that Allow basic authentication is set to disabled.

Since this is a security risk (there is no encryption with basic authentication) and only a few device really need to connect, We decided to create a new policy that enabled this for only admins that will need to use Exchange Online PowerShell and use security filtering to only apply to a security group with the required devices.

Once basic authentication was re-enabled I was able to connect without issue.

If you have this issue and apply either the CIS or the Windows 10 baseline policy this could be the cause.

VMware PowerCLI Integrated Authentication Issues

Recently we have been having an issue with VMware PowerCLI not passing through the users credentials when running Connect-viserver to connect to our vCenter servers.

This has been causing problems when trying to use scheduled task to automated reports and run remediation task like removing old snapshots or reporting on VMware Tools versions as it is prompting for credentials.

For integrated authentication to work, the vCenter servers needs to be setup to allow single sign on for the domain that you will be connecting from, so confirm that your Active Directory Identity source is added and that SSO works from the web client. If not, complete this first before trying to use PowerCLI with integrated authentication.

I have SSO configured and tested so this wasn’t my issue.

When using the older version of PowerCli version 6.5 and below we had no issue with integrated authentication and would connecting to vCenter server without prompting me for credentials.

We could continue to use the old version of PowerCLI but we would be missing out on improvement and new commandlets so I wanted to try and get the newer version working for automated task.

First we install the VMware.PowerCLI module using Install-Module VMware.PowerCLI, the current version is 12.1

When I tried to connect using this version of PowerCLI I get prompted for a user name and password and this is what is stopping my automated task from running.

There are a few ways to workaround the prompt and this can also be used to confirm if SSO is working correctly. One way would be to add credential store item that can be used for connecting.

To add this use the VICredentialstore commandlet.

New-VICredentialStoreItem -User domain\username -Password Password -Host vc.domain.local -File C:\Temp\vicreds.xml

This outputs the credential to an xml file that can then be imported and called using Connect-VIserver.

$logon = Get-ViCredentialStoreItem -File C:\Temp\vicreds.xml
Connect-VIServer -Server $logon.Host -User $logon.User -Password $logon.Passwor

This works but I don’t really want to have a xml file that has information saved to it and someone might remove the folder or file by mistake.

The other way would be similar but using a txt file with the converted to a secure string password but again this relies on a file which is not ideal and not really all that secure.

The last option and one that I wouldn’t recommend at all is to hard code a username and password in the script.

So now that we have gone through some work arounds I decided to have a look at the actually problem .

The above proves that authenticating against AD is working so I knew it wasn’t an account or SSO issue so it had to be an issue with PowerCLI itself.

I connect using a my user name and passwords and it connect without issue.

I then check the VPX log under /storage/log/vmware/vpxd to see if there are an issue but I didn’t see any issues.

Next I tried to use the -verbose parameter to return more information on what exactly connect-viserver was doing,

This then returned an error for TLS.

I next checked the settings on PowerCLI configuration settings.

To check the PowerCLI configuration use

Get-PowerCLIConfiguration

When checking the configuration the Invalidcerificaeaction was set to unset.

I changed this setting to warn instead of unset

Once this setting was changed I can now connect to PowerCLI with integrated authentication, I do get a long warning message though I could set this to ignore and this returns no warning or error.

There are two ways around this instead of changing the above setting. One is to install the the certificate as a trusted root certificate so that the cert is trusted.

Or if you have an internal certificate authority you to replace the default VMware cert with an internal cert.

Once this is done the connection work without requiring manual intervention and my automated scripts can be run using scheduled tasks again with the latest version of PowerCLI. Hopefully this will be helpful to anyone else having this issue.

Microsoft Graph API Result Size Limit

Recently we have been running some Microsoft Graph API queries and were not getting back all the results expected.

Microsoft Graph seems to have a limit of 1000 results for signin logs, when the limit is reached graph will then start paging the result and adding them to @odata.nextLink property.

There is a Microsoft doc on paging in Graph.

Paging Microsoft Graph data in your app – Microsoft Graph | Microsoft Docs

There are different limits depending on the API.

Below is an extract from the paging doc.

Paging behavior varies across different Microsoft Graph APIs. Consider the following when working with paged data:

  • Different APIs might have different default and maximum page sizes.
  • Different APIs might behave differently if you specify a page size (via the $top query parameter) that exceeds the maximum page size for that API. Depending on the API, the requested page size might be ignored, it might default to the maximum page size for that API, or Microsoft Graph might return an error.
  • Not all resources or relationships support paging. For example, queries against directoryRoles do not support paging. This includes reading role objects themselves as well as role members.

The @odata.nextLink then needs to be called to get the addtional results.

When we run a query and the results are under the limit there will be two objects returned

@odata.context and value

If we run a query that goes over the max results limit of 1000 the value object is changed to @odata.nextLink

If we use count on the $Results variable it returns 996 items.

To query the addtional results we need to loop through each page to extract the results.

To loop through the results we can create a new variable with the @odata.nextLink and use while loop to go through the variable to get results from the pages.

When we do this the $results count go up to 1142

Below is the full script to get the addtional results.

$ApplicationID = ""
$TenatDomainName = ""
$AccessSecret = Read-Host "Enter Secret"


$Body = @{    
Grant_Type    = "client_credentials"
Scope         = "https://graph.microsoft.com/.default"
client_Id     = $ApplicationID
Client_Secret = $AccessSecret
} 

$ConnectGraph = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenatDomainName/oauth2/v2.0/token" `
-Method POST -Body $Body

$token = $ConnectGraph.access_token

$LoginUrl = "https://graph.microsoft.com/v1.0/auditLogs/signIns"
$LoginResults = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Token)" } -Uri $LoginUrl -Method Get

$Results = @()
$Results += $LoginResults.value

$Pages = $LoginResults.'@odata.nextLink'
while($null -ne $Pages) {

Write-Warning "Checking Next page"
$Addtional = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Token)" } -Uri $Pages -Method Get

if ($Pages){
$Pages = $Addtional."@odata.nextLink"
}
$Results += $Addtional.value
}

If using the Microsoft Graph SDK the process is much simpler.

Once connect to using Connect-Mgraph we can then run

Get-MgAuditLogSignIn | 
Select-Object UserDisplayName,UserPrincipalName,IPAddress,AppDisplayName,ResourceDisplayName,ClientAppUsed,CreatedDateTime

The $signins results variable returns the same 996 results as we got with the above invoke-restmethod graph api query.

To get all the addtional results all we need to do is add the -All parameter and this should then return all results.

This shows the two different method to get the larger results from GraphAPI queries.

Upgrading ESXI Host From 6.7 to 7.0 Using vSphere Lifecycle Manager

In this post we will go through using vSphere Lifecycle Manager VLM to upgrade an ESXI host from 6.7 to 7.0. Lifecycle Manager replaces vSphere Update Manager in vCenter server 7.0 the process is pretty much the same as in VUM.

Before upgrading to a new version of ESXI first step should be to check VMware compatibility, this can be done by either checking the VMware compatibility matrix.

VMware Compatibility Guide – System Search

Or in VLM we can now use Hardware compatibility, This syncs a list of compatible hardware and this can then be checked directly on the host to verify if the ESXI host hardware is supported.

To check using VLM, Open the vSphere web client > Menu > Lifecycle Manager

We then need to sync the hardware compatibility list. Click Actions > Sync HCL

Once synced we can run a compatibility check from the Host > Updates > Hardware Compatibility

After the compatibility is all confirmed and no issues are found, we can go ahead with the upgrade.

Next we need to download the ISO image for ESXI 7.0 that will be imported to VLM and used in the upgrade baseline.

Download VMware vSphere – My VMware

To import the ISO go back to VLM > Imported ISOs > Import ISO

Click browse and select the ESXI ISO that was downloaded earlier.

The ISO will then start to import.

The ISO should now show under Imported ISOs

Next we need to create a new upgrade baseline, this can either be done under baseline or by selecting the image and clicking on New Baseline.

Give the baseline a name

Select the ISO to be used

Click next and finsh off the baseline

Check baselines to confirm the creation has completed.

The baseline can be assigned to the host individually or the cluster. I am going to apply to the cluster. Go to the Cluster and select Updates > Attach.

Select the upgrade baseline.

We can check the compliance for the baseline for all host in the cluster.

To remediate you can either do this from the cluster or on the individual host. I will remediate from the host itself.

Go to the host, Select Updates > Baseline > Upgrade Baseline > Remediate

Accept the end user agreement.

The upgrade will do a remediation pre check before allowing the upgrade.

Once you click Remediate, the upgrade task will start

The host should now reboot and start the upgrade.

When we check the baseline the host should now show as compliant and running ESXI 7.0.

Upgrading a host using VLM is a straight forward process and makes it easy to keep your ESXI host at the latest release version.