Tag: PowerShell

Automate and Deploy Microsoft Defender Advanced Threat Protection (MDATP) via PowerShell

A few days ago, I needed to on-board Azure Windows Server VMs with Microsoft Windows Defender Advanced Threat Protection, or in short, MDATP. Sometimes Azure Security Center (ASC) has issues with on-boarding VMs and deploying the MDATP agent. As a result, I wrote the following PowerShell script that will download the MDATP.cmd file from my Azure Blob container and install it locally to the VM. This script allows you to automate it for many VMs to the scope of a Resource Group.

Now there are a few assumptions here…

  1. Download the MDATP.cmd file from the Defender Security Center portal
  2. Remove the requirement for user consent for the MDATP execution
  3. Upload the modified MDATP file to an Azure Blob container
  4. Generated a SAS URI for the MDATP file

There are many examples on the Internet on how to go step #4. Maybe in time I will do another post.

To remove the requirement of the MDATP agent to execute based on user interaction/consent can be done by removing, or commenting out the following lines of code. Launch the MDATP.cmd file within Notepad, and add a “:” before each line of code from lines 9 through 19, except line 14. Should look something like this.

Now, update and run the following PowerShell code. You can validate the VM is calling back to the Defender Security Center portal or by running the MDATPClientAnalyzer on the VM.

#update resource as needed
$resourcegroup = "YOUR_RESOURCE_GROUP"
#get only Windows Server VMs
$vms = Get-AzVM -ResourceGroupName $resourcegroup | Where-Object {$_.StorageProfile.OSDisk.OSType -eq "Windows"} | Select-Object Name
foreach ($vm in $vms)
    #friendly start message to indicate which server has started
    Write-Host "Server $vm has started..."
    #create folder, do not display error if folder already exists
    New-Item -Path "C:\" -Name "MDATP" -ItemType "directory" -ErrorAction SilentlyContinue
    #download MDATP.cmd file from Storage Account with SAS URI. Execute the cmd file. Passing "Y" to continue with installation.
    Invoke-WebRequest -Uri "YOUR_URI_SAS" -OutFile WindowsDefenderATPLocalOnboardingScript.cmd; Start-Process -FilePath "C:\MDATP\WindowsDefenderATPLocalOnboardingScript.cmd" -Verb RunAs
    #sleep for 5 seconds
    Start-Sleep -Seconds 5
    Restart-Computer -ComputerName $vm
    #friendly finished message to indicate which server has completed and will now reboot
    Write-Host "Server $vm has completed, reboot initiated..."

Get Azure Global Administrators

Recently a customer asked me to retrieve all users that have Global Administrator access to their Azure environment. The PowerShell code below will allow you to query the Azure environment against Azure Active Directory (AAD). Nothing new here or unique here, but this quick two-liner should do the trick. 😉

$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq 'Company Administrator'}
Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId | Sort-Object DisplayName | Select-Object DisplayName, UserPrincipalName, ObjectId 

Hope this was helpful!

Forcefully Revoke Azure AD User Session Access – Immediately

Sometimes it is critical to revoke a user’s Azure AD session for whatever reason it may be. You can always delete the user from Azure AD, however if the user is connected via PowerShell, the user’s token may not expire for a few more minutes, or maybe hours, depending on the token TTLs settings… So what can you do? You can forcefully revoke a user’s token session by using the following PowerShell cmdlet, “Revoke-AzureADUserAllRefreshToken“. Due to Microsoft’s ever changing Azure modules, I have tested this solution within the Azure Cloud Shell, and not on a local machine with PowerShell ISE with the AZ or RM modules.

First we need to identify which user will have its access revoked. Based off of the Revoke cmdlet, you will need to specify the “ObjectID” parameter, and the user’s ObjectID can be found within the Azure AD blade as seen below:

For additional information you can view the user’s access by executing the following cmdlet, “Get-AzRoleAssignment -ObjectId <>

Once we have identified the user and its ObjectID, we first need to connect to Azure AD, this is done by running the following cmdlet, “Connect-AzureAD -TenantId <>“. With my experience you need to specify the TenantID. Once you have connected, and verified your device, you can now run the Revoke cmdlet, as seen below, the following cmdlet needs to be executed, “Revoke-AzureADUserAllRefreshToken -ObjectId <>“. The Revoke cmdlet will not provide any details if the operation was successful, however it will throw an error if something did not go right — yes, very helpful, right? 🙂

By running this Revoke cmdlet, the user has now lost all access to its Azure AD account and any active sessions, either via the Azure Portal UI, or PowerShell will be immediately revoked. 🙂

Step-by-Step – Installing System Center Operations Manager (SCOM) 2019 on Windows Server 2019 with SQL 2017

This post I will be installing System Center Operations Manager 2019 (SCOM) RTM, Build Number 10.19.10050.

Here is some of the background information. As this post will concentrate on the installation of SCOM 2019, I am going to omit the setup and configuration of the Domain Controller, Windows Server 2019 for the SCOM Management Server. Also to note, I am using a PaaS instance of SQL 2017 (hosted on Azure), likewise the entire environment lives on Azure in an IaaS and PaaS configuration.

Service Accounts and Local Administrator:

DomainAccount Description Local Admin on…
domainSCOM_AA SCOM Action Account SCOM
domainSCOM_DA SCOM Data Access/SDK Account SCOM
domainSCOM_SQL_READ SCOM SQL Reader n/a
domainSCOM_SQL_WRITE SCOM SQL Writer n/a
domainSCOM_Admins SCOM Administrators Group SCOM
domainSQL_SA SQL Service Account n/a

Now, if you’re lazy like me, or are tired of doing this setup for environments, I have scripted the automation of these accounts. You can find that link here, Microsoft TechNet Gallery.

Let’s Begin:

Since I am hosting SQL on a dedicated server, I will install SSRS (SCOM Reporting) on that server.

Well, that’s not new… Prerequisites. Since this is a clean, vanilla Windows 2019 server, we will need to install all the necessary Web Console components, along with Report Viewer Controls (probably SQL CLR Types too..).

  • For the Report Viewer Prerequisites, go HERE.
  • Here is the PowerShell command I ran to install the necessary IIS features/roles:
Import-Module ServerManager
Add-WindowsFeature Web-Server, Web-WebServer, Web-Common-Http, Web-Default-Doc, Web-Dir-Browsing, Web-Http-Errors, Web-Static-Content, Web-Health, Web-Http-Logging, Web-Log-Libraries, Web-Request-Monitor, Web-Performance, Web-Stat-Compression, Web-Security, Web-Filtering, Web-Windows-Auth, Web-App-Dev, Web-Net-Ext45, Web-Asp-Net45, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Mgmt-Tools, Web-Mgmt-Console, Web-Mgmt-Compat, Web-Metabase, NET-Framework-45-Features, NET-Framework-45-Core, NET-Framework-45-ASPNET, NET-WCF-Services45, NET-WCF-HTTP-Activation45, NET-WCF-TCP-PortSharing45, WAS, WAS-Process-Model, WAS-Config-APIs -restart


Once the server is back online, you will need to register ASP.Net.


You will need to apply the following using Command Prompt (as Administrator)). Yes, this is a screenshot from a previous post…Forgot to capture the screenshot when running it this time..

  1. cd %WINDIR%Microsoft.NETFramework64v4.0.30319
  2. aspnet_regiis.exe -r
  4. Reboot your server…

Once the server is back online, let’s try that Prerequisites check again….

Great! Now all of Prerequisites have been met!

Provide a meaningful Management Group Name (there’s no going back after this…)

SQL Server will be where your SCOM SQL instance(s) were installed. Remember, to either disable the Windows Firewall, or open SQL TCP Ports 1433.


I recommend always keeping this off, and manually updating your SCOM infrastructure.

One quick review. Looks good. Hit Install, and get some fresh air!

A few minutes later….

Sweet! All good. I hope this helps. If you have any questions or issues, please drop me a line.

Happy 2019 SCOM’ing!


Data Deduplication in Windows Server 2019

When Windows Server 2016 was released, Data Deduplication was not available for ReFS file system, and only available for NTFS. With Windows Server 2019, data deduplication is now available for both NTFS and ReFS file systems.

Data Deduplication is a great technology that allows you to reduces your storage footprint by removing any duplicated data blocks and replacing it with metadata.

In the scenario below, I will show you how to enable Data Deduplication and tracking the ‘saving rate’ of the data deduplication.

Install-WindowsFeature FS-Data-Deduplication

This cmdlet will allow you to install the feature. In most scenarios, ie. Storage Spaces Direct, Hyper-V, this will make most sense. Also, this cmdlet would need to be executed on all nodes.

Get-Command *Dedup*

Now that we have data deduplication installed, we can now see all the of the cmdlets available.

Enable-DedupVolume -Volume "E:","F:" -UsageType HyperV

Finally, once we enable data deduplication on the volumes, we can now track the saving rate. Note, this can be done via PowerShell, or Windows Admin Center (WAC). Note, this can only be enabled on Cluster Shared Volumes (CSV).


I hope this helps, and now you can start minimizing the data deduplication within your environment.

System Center Operations Manager (SCOM) 2019- Requirements for Windows Server 2019 via PowerShell

The following PowerShell code is to install all the necessary IIS components for System Center Operations Manager (SCOM) 2019 Web Console on Windows Server 2019.

Import-Module ServerManager
Add-WindowsFeature Web-Server, Web-WebServer, Web-Common-Http, Web-Default-Doc, Web-Dir-Browsing, Web-Http-Errors, Web-Static-Content, Web-Health, Web-Http-Logging, Web-Log-Libraries, Web-Request-Monitor, Web-Performance, Web-Stat-Compression, Web-Security, Web-Filtering, Web-Windows-Auth, Web-App-Dev, Web-Net-Ext45, Web-Asp-Net45, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Mgmt-Tools, Web-Mgmt-Console, Web-Mgmt-Compat, Web-Metabase, NET-Framework-45-Features, NET-Framework-45-Core, NET-Framework-45-ASPNET, NET-WCF-Services45, NET-WCF-HTTP-Activation45, NET-WCF-TCP-PortSharing45, WAS, WAS-Process-Model, WAS-Config-APIs, web-asp-net -restart

You can also find this in Microsoft’s TechNet Gallery, HERE.

Deploy an Azure Cloud Witness for your Failover Cluster Quorum for Windows Server 2016 & 2019 with PowerShell

For the longest time, when deploying a cluster with Windows Server, you only had the two options,

  1. Using a dedicated disk for the quorum, or
  2. Configuring an SMB file-share as the quorum witness

With Server 2016 and 2019, there is now a third option, Cloud Witness. The Cloud Witness leverages Azure Blob storage to provide that additional cluster/quorum vote.

Before showing you how this is done, one should understand the purpose of a witness/quorum is with respect to a failover cluster.

When one or more members of a cluster stops reporting to the other cluster members, there is a vote. The vote ensures that there is no split-vote, and ensures the cluster has a true owner. For example, in a two node cluster, if each node believe it is the owner, then this will cause a “split-brain”. In short, neither node will ever agree it is the owner (or not). This is where a quorum is required to determine who is the owner by providing the third vote, ie. majority. This ensures the cluster has a true owner by having the majority of votes. Each member gets a vote, plus the quorum.

Why this matters, in the even there is no quorum, a node from the cluster can be evicted and as a result will suspend all application services to prevent data corruption by more than one system writing data without the cluster services coordinating data writes and access. Depending on policies, VMs running on the ejected cluster member will either suspend operations or be migrated to other nodes before being ejected.

Below is a step-by-step guide on how to configure the Azure Blob storage as the Cloud Witness.


  • The Azure Blob storage account has already been created,
  • The cluster with at least 2 nodes already exists.

Launch the PowerShell console as Administrator, and execute the following cmdlet:

Set-ClusterQuorum -CloudWitness -AccountName "storage_account_name" -AccessKey "primary_access_key"

Now if we go back to the Failover Manager console we can see we have successfully configured cluster with a Cloud Witness.

In conclusion, deploying a Cloud Witness for a Failover Cluster is very simple, and in case of power outage in one datacenter, maintenance on a node, etc. then the entire cluster and its members (nodes) are all given an equal opportunity. Not only is it recommended and a requirement for 2-node clusters, but for any number of nodes, having a quorum is key ensuring high-availability.  As mentioned, there are the traditional options such as using a dedicated disk or a file-share (SMB) as the cluster witness. However with Azure Blob storage with its 16×9 uptime, we can always ensure the quorum witness is online and available.

DNS commands (Command Prompt vs PowerShell)

Recently I discovered Windows PowerShell has the ability to clear the local DNS on a machine, just like the traditional Command Prompt. Below is a table of the most common commands I personally use on a day-to-day basis and its PowerShell equivalent(s). Of course there are more PowerShell cmdlets, see the URL below for the complete list.

Command Prompt PowerShell Description
ipconfig /flushdns Clear-DnsClientCache Clears the contents of the DNS client cache.
ipconfig /registerdns Register-DnsClient Registers all of the IP addresses on the computer onto the configured DNS server.
ipconfig /displaydns Get-DnsClientCache Retrieves the contents of the DNS client cache.


Flush DNS Cache with PowerShell

For years I have always been using Windows’s command prompt to flush the DNS cache on a local machine. As we know, that command is pretty well known, “ipconfig /flushdns“. Turns out there is an equivalent command we can run within the PowerShell console, and that is, “Clear-DnsClientCache“. Clear-DnsClientCache does exactly what it states, it clears the contents of the DNS client cache/local machine. Consider this next time you need to flush the local machine’s DNS cache.


Connect Batch of Azure VMs to Log Analytics (OMS) via PowerShell

So, you have a bunch of Virtual Machines (VMs) in Azure, and didn’t used an ARM template, and now need to connect the VMs to Log Analytics (OMS). Earlier this month, I demonstrated on this can be done with the ARM portal, here’s that blog post. Of course, this has to be done individually and can be very tedious if you have 10’s or 100’s of machines to do this to… All I can think of is PowerShell!

Here is a script I tweaked that Microsoft has already provided but for a single VM. I have just tweaked it to automate and traverse through your entire resource group, and add ALL VMs within the RG to Log Analytics.

Here is the link to Microsoft TechNet for that script. Please test it out and let me know. And if it helped you out, please give it a 5 start rating.

Microsoft TechNet PowerShell Gallery

If all went well, your before and after should look similar to this. I had two test VMs in my Resource Group.