As a big adovcate of PowerShell Scripts in Microsoft Endpoint Manager, I definitely welcome the recent changes which Microsoft have implemented. This will have some positive effects on most organisations but maybe not as welcomed by others and heres why?
In my experience some organisations like to leverage PowerShell to modify applications that have been installed using Win32 apps. An example I have experience within this space is Java ( Oh the horror ). This organisation still required a fat install of java to run a legacy application and Java was inserted using GPO with reg hive modified to prevent the regular and annoying pop up for updates.
So to address this we installed Java via W32 apps and used a PowerShell script from Microsoft Endpoint Manager to modify the key.
What you will probably need to do is allow your script to fail. Once the script has failed, the Win32 apps will then be installed, and If the script fails, the Intune management extension agent retries the script three times for the next three consecutive Intune management extension agent check-in. The check in period is every 60 minutes so in that time you should have succesfully installed all Win32 apps.
Here is the new channges for PowerShell scripts.
PowerShell scripts execute before apps, and time out reduced
There are some updates to PowerShell scripts:
Microsoft Intune management extension execution flow is reverted back to processing PowerShell scripts first, and then running Win32 apps.
To resolve an Enrollment Status Page (ESP) time out issue, PowerShell scripts time out after 30 minutes. Previously, they timed out after 60 minutes.
Sometimes when working with PowerShell scripts you may need to import a particular source file. You could specify a variable pointing directly to the file but using the below function provide a more flexible solution.
Sometimes when working with customers you need to validate if a particular port has been opened on their Firewall. I am unable to count how many times I’ve had a discussion where a port hasnt been opened. So for simplicity the following PowerShell function allows you to check instantly;
Function Get-CheckPort{
[cmdletbinding()]
Param (
[parameter(Mandatory=$true)]
[string]$ipaddress,
[string]$port
)
# End of Parameters
Process{
$Date = Get-Date
$MyDate = " " + $Date.Day + "." + $Date.Month + "." + $Date.Year + " " + $date.Hour + ":" + $date.Minute
Try{
$connection = $null
$connection = New-Object System.Net.Sockets.TcpClient($ipaddress, $port)
}
Catch{
Write-host "Warning: Port $port is closed - $MyDate" -ForegroundColor Red
}
if ($connection.Connected){
Write-Host "Info: Port $port is open - $MyDate" -ForegroundColor Green
}
}
}
Get-CheckPort -ipaddress '' -port ''
As you can see from the test above, I am to validate that port 80 to the teams.microsoft.com is open
I have recently come across an amazing new PowerShell module which allows you to export/import your Conditional Access policies. This module is brilliant if your someone like who loves a bit of PowerShell and baselines their configuration so it can be reused for other customers.
The following Microsoft Graph API permissions are required for this to work: Policy.ReadWrite.ConditionalAccess Policy.Read.All Directory.Read.All Agreement.Read.All Application.Read.All
Also, the user running this (the one who signs in when the authentication pops up) must have the appropriate permissions in Azure AD (Global Admin, Security Admin, Conditional Access Admin, etc).
Export your Conditional Access policies to a JSON file for backup.
Learn more about the different Conditional Access commands in DCToolbox.
help Export-DCConditionalAccessPolicyDesign -Full
help Import-DCConditionalAccessPolicyDesign -Full
help New-DCConditionalAccessPolicyDesignReport -Full
help New-DCConditionalAccessAssignmentReport -Full
Activate an Azure AD Privileged Identity Management (PIM) role.
Enable-DCAzureADPIMRole
User sign-in will popup and the after signing in, the following will happen:
VERBOSE: Connecting to Azure AD...
*** Activate PIM Role ***
[1] User Account Administrator
[2] Application Administrator
[3] Security Administrator
[0] Exit
Choice: 3
Duration [1 hour(s)]: 1
Reason: Need to do some security work!
VERBOSE: Activating PIM role...
VERBOSE: Security Administrator has been activated until 11/13/2020 11:41:01!
In many organisations where governance around the creation of Microsoft Teams is currently not in place. You may come across Teams where the owner may have left the organisation but the Team is still active. So using PowerShell we can find which Teams have or do not have owners.
Prerequistes
Microsoft Teams Module needs to be installed
Install-Module MicrosoftTeams
PowerShell Script
The following script will obtain all the required information and export to CSV.
When working with Azure Active Directory Connect you may experience issues with account duplicating due to the ImmutableID not matching. If it does happen its is a pain to resolve as you have to;
Desynchronize the affected accounts Delete from the Deleted Users OU in Azure Active Directory Obtain the on-premises ImmutableID Obtain the cloud ImmutableID Compare the IDs Set the cloud ID with the on-premises ID
Now wouldnt it be easier if someone had a bunch of PowerShell commands to help you get the ImmutableID. This is where I come in
Obtaining ImmutableID from on-premises Active Directory Object
The following PowerShell script extracts all the ImmutableID’s from every single Active Directory User Object and store in a CSV file on your desktop.
Obtaining ImmutableID from Azure Active Directory Object
The following PowerShell script extracts all the ImmutableID’s from every single Azure Active Directory User Object and store in a CSV file on your desktop.
When I have had to compare the two exports at scale for an entire environment, it can be a complete nightmare but the ImportExcel module was brilliant in getting the data merged into a single sheet.
Sometimes accidents happen and things get deleted by mistake but what do you do if you delete a Microsoft Team by mistake?
When the team is deleted, it is held in the “recycle bin” for 30 days until it is permanently deleted. The following is the process of restoring a deleted team in Microsoft Teams.
Once Team is deleted, option to recover it exists for up to 30 days
All of it including (Channels, files, tabs, etc.) will reappear as it was before
Restore can take up to 4 hours
To restore, from exchange admin center, select recipients, then groups
Locate the group (only if soft deleted)
Select the group and choose restore
This is where my favourite Microsoft tool comes into action, PowerShell
Prerequisites
AzureAD Module is installed Global Admin to your Azure AD Tenant
Process
Launch PowerShell as an administrator.
1
Connect-AzureAD
When a team is created in Microsoft Teams, it creates an Office 365 group. In order to restore the group you will need to obtain the Id using the following cmdlet
But what I wanted to pick up on is the new PowerShell elements within this service release as its something I regular do within my own Windows 10 deployments.
These are really cool additions.
View PowerShell scripts in the Intune Troubleshooting pane
You can now view your assigned PowerShell scripts in the Troubleshooting pane. PowerShell scripts provide Windows 10 client communication with Intune to run enterprise management tasks, such as advanced device configuration and troubleshooting. For more information, see Use PowerShell scripts on Windows 10 devices in Intune.
Win32 app support for Workplace join (WPJ) devices
Existing Win32 apps are supported for Workplace join (WPJ) devices. PowerShell scripts, which are not officially supported on WPJ devices, can be deployed to WPJ devices. Specifically, device context PowerShell scripts work on WPJ devices, but user context PowerShell scripts are ignored by design. User context scripts will be ignored on WPJ devices and will not be reported to the Microsoft Endpoint Manager console. For more information about PowerShell, see Use PowerShell scripts on Windows 10 devices in Intune.
With Office 365 Service Communications API you can pull the required Current Status using PowerShell providing you have completed the prerequisites below.
The TenantID, ClientID and ClientSecret are obtained from your Application but please do remember you need to have a copy of the ClientSecret as once you move away from the secret. You wont be able to see it again.
The Script
Clear-Host
<#Information
Author: thewatchernode
Contact: author@blogabout.cloud
Published: 30th Ocotber 2020
.DESCRIPTION
Tool to gather Microsoft 365 Health Status.
# IMPORTANT
Office 365 Service Communications API needs to be configured with your Tenant. http://www.blogabout.cloud/2020/10/1884/
Version Changes
: 0.1 Initial Script Build
: 1.0 Initial Build Release
Credit:
.EXAMPLE
.\Get-Microsoft365Status.ps1
Description
-----------
Runs script with default values.
.INPUTS
None. You cannot pipe objects to this script.
#>
#region To be configured by the script runner
# Objects
$tenantId = ''
$client_id = ''
$client_secret = ''
#endregion
Function Get-M365Status {
# Construct URI for OAuth Token
$uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
# Construct Body for OAuth Token
$body = @{
client_id = $client_id
scope = "https://manage.office.com/.default"
client_secret = $client_secret
grant_type = "client_credentials"
}
# Get OAuth 2.0 Token
$tokenRequest = try {
Invoke-RestMethod -Method Post -Uri $uri -ContentType "application/x-www-form-urlencoded" -Body $body -ErrorAction Stop
}
catch [System.Net.WebException] {
Write-Warning "Exception was caught: $($_.Exception.Message)"
}
$token = $tokenRequest.access_token
# Get Office 365 Status
$m365status = try {
Invoke-RestMethod -Method Get -Uri "https://manage.office.com/api/v1.0/$tenantid/ServiceComms/CurrentStatus" -ContentType "application/json" -Headers @{Authorization = "Bearer $token"} -ErrorAction Stop
}
catch [System.Net.WebException] {
Write-Warning "Exception was caught: $($_.Exception.Message)"
}
# List service overview status
$m365status.Value | Format-Table WorkloadDisplayName, StatusDisplayName, Status, IncidentIds
}
Write-host 'Version information - You are running script version 1.5' -ForegroundColor $White -BackgroundColor $DarkGray
@'
┌─────────────────────────────────────────────────────────────┐
Gather the status of Microsoft 365 Service Health
Follow @thewatchernode on Twitter
└─────────────────────────────────────────────────────────────┘
'@
Start-Transcript -Path $InstallDir\M365Status_Log.txt
Get-M365Status
Stop-Transcript
PowerShell module can sometimes become a nightmare if there are dependencies on other modules. I have been recently looking at my AzureADPreview which had one dependency for;
– Microsoft365DSC module
If you run the standard uninstall-module -name AzureADPreview you will receive an error stating the module cannot be uninstalled due to the dependency of the other module as shown below;
If you run install-module AzureADPreview you are likely to receive a duplicate install of the same module which will potential cause issues later down the line.