Scenario: Do you have a common command, function, or script that you always execute manually within PowerShell at Startup? For example in my case, a .ps1 file that contains functions with how to connect to specific remote PowerShell instances.
Solution:
Run this within PowerShell:
New-item –type file –force $profile
Then edit the file it creates Microsoft.Powershell_profile.ps1 (usually located in this directory: C:\Users\<username>\Documents\PowerShell\) with the call to the script, the function, the commands, etc. Every time you open PowerShell, it will automatically run it and will be ready for you.
Category: Powershell
Search-Mailbox: Easy way to convert String values to Integers
Scenario: Need an easy way to convert the [string] value into a number? Specifically for the Search-Mailbox command for the ResultItemsCount and ResultItemsSize?
Solution:
Command:
$Search = Search-Mailbox $mbx -SearchDumpster -SearchQuery Received:1/1/1900..1/1/2013 -EstimateResultOnly
Now convert the results and store in a variable:
Note: $ItemSize is in Bytes.
$ItemCount = ($Search.ResultItemsCount) -as [int]
$ItemSize = (([regex]::match($Search.ResultItemsSize, $regex).Groups[1].value) -replace " bytes","" -as [int])
STOP THAT Print Spooler!
Scenario: With some of the latest exploits, stop that print spooler on your servers if its unneeded
Solution: PowerShell Scriptlets
If you are on the server, run the following:
Set-service Spooler -startuptype disabled
stop-service Spooler
get-service spooler
OR
If you want to remotely run the commands, like the big bad admin that you are, run the following:
$s = "ExServer1","ExServer2"
$s | %{
$n = $_
"Disabling Spooler on $_"
Invoke-Command -ComputerName $n -ScriptBlock { Set-service Spooler -startuptype disabled }
Invoke-Command -ComputerName $n -ScriptBlock { stop-service Spooler}
}
Add AD Tools to Computer via PowerShell
Scenario: You want to quickly install the AD tools (Active Directory Users and Computers and other AD utilities) via PowerShell.
Solution: Run PS as Admin and run the following: ADD-WindowsFeature RSAT-Role-Tools
MSExchangeEdgeSync Service will not Start
Scenario: After making some AD Sites and Service Changes, the MSExchangeEdgeSync service will not start.
Solution: Run the following commands to list all of the Edge Sync Service Configs and to add the new AD Site:
Get-edgesyncserviceconfig
New-edgesyncserviceconfig -site <New AD Site>
Configure your Exchange Online PowerShell Script to leverage OAUTH/Modern Authentication and Authenticate Silently
Scenario: You need to connect to Exchange Online PowerShell via a script that will silently authenticate using Modern Authentication/OAuth.
Microsoft is deprecating Legacy/Basic Authentication when connecting to Exchange Online. Your existing scripts that leverages a username/password to authenticate silently, either by hardcoding a username or password into the script OR using encrypted keys that PowerShell calls in, will break when legacy authentication is officially disabled. You will need to convert the logic us to now start connecting to Exchange Online via Modern Authentication/Oauth.
If you haven’t yet asked ‘How to do we do that’? I am glad I asked for you….
1. You need the latest release of the ExchangeOnlineManagement (Connect-ExchangeOnline) module installed in PowerShell : Install-Module -name ExchangeOnlineManagement.
2. Setup App-only application in Azure.
2a. Register a new application object in Azure Active Directory
2b. Provide the Azure applications the following API permission: Exchange.ManageAsApp
2c. Create a self-signed cert in PowerShell that will be used to authenticate to the Azure App.
# Create certificate
$mycert = New-SelfSignedCertificate -DnsName “whatever.com” -CertStoreLocation “cert:\LocalMachine\My” -NotAfter (Get-Date).AddYears(3) -KeySpec KeyExchange
#Export certificate to .pfx file
$mycert | Export-PfxCertificate -FilePath c:\temp\mycert.pfx -Password $(ConvertTo-SecureString -String “PasswordForCert!” -Force -AsPlainText)
#Export certificate to .cer file
$mycert | Export-Certificate -FilePath c:\temp\mycert.cer
2d. Upload the Certificate in the Certificates & Secrets of the Azure App.
3. Assign the Exchange Administrator role (via Azure Roles or MSOL Roles) to the new Registered App.
4. Now that the app is configured with Exchange Permissions, Exchange Access, and the Certificate uploaded, connect to Exchange Online using the pfx Cert from PowerShell:
Connect-ExchangeOnline -CertificateFilePath “C:\temp\mycert.pfx” -CertificatePassword (ConvertTo-SecureString -String “PasswordForCert!” -AsPlainText -Force) -AppID “<AppID of your new registered app>” -Organization “<your tenant organization name>”
Error: PackageManagement\Install-PackageProvider : No match was found for the specified search criteria for the provider ‘Nuget’
Scenario: When attempting to install the newer Exchange Online Management PowerShell tools, you receive a wall of red errors similar to the following:
PackageManagement\Install-PackageProvider : No match was found for the specified search criteria for the provider ‘Nuget’
PackageManagement\Get-PackageProvider : Unable to find package provider ‘NuGet’. It may not be imported yet.
Install-Module : NuGet provider is required to interact with NuGet-based repositories.
Solution: Run PowerShell as Administrator and run the following:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Get a list of users assigned to a Microsoft Online Role
Scenario: You need to produce a list of all users that are assigned to a Microsoft Online Administrative Role.
Scriptlet:
$role_user = @()
$roles = Get-MsolRole
$roles | Sort name | %{
“Checking Role: $($_.name)”
$role_User += Get-MsolRoleMember -RoleObjectId $_.ObjectId
}
Running PowerShell commands against a large group of mailboxes or returning large data returns
Scenario: While attempting to run Exchange Online PowerShell commands against a large group of mailboxes and/or returning large datasets, you may run into mico delays or other errors once you breach any number of throttles that Microsoft Online imposes against your PowerShell session. Although throttles protect Microsoft Online for good reason, your still left with the question “WHY ME?” and how do we get around these strict restrictions.
Solutions: There’s a few ways to execute commands in Exchange Online PowerShell, but each have their own advantages and disadvantages. Below are a few examples with running the command: get-mobiledevicestastics which is naturally heavy in processing and subject to breaching throttles.
Standard Command – This may work if you only have a small number of mailboxes in your environment. Its quick, but also dangerous.
$AllMailboxes.alias | Get-mobiledevicestatistics -mailbox $_
ForEach with a Mini-Sleep – This command will help with some of the throttling, its not difficult to execute by implementing a 2-command loop and will help with the recharge rate for how many commands you are allowed to execute within a time period.
$AllMailboxes.alias | %{ Get-mobiledevicestatistics -mailbox $_; Start-Sleep -milliseconds 500}
-or-
$AllMailboxes.alias | ForEach { Get-mobiledevicestatistics -mailbox $_; Start-Sleep -milliseconds 500}
Invoke-Command to help with Large Data Return – Invoke with Select-Object forces the O365 servers run the command and limits the data returned. This takes your local client out of the loop helping to ease local client throttling. HOWEVER invoke command doesn’t allow complex PowerShell commands either.
Invoke-Command -session (Get-Pssession) -scriptblock {Get-mobiledevicestatistics -mailbox $_ | select-object identity, Device*,LastSuccessSync}
-or-
Invoke-Command -session (Get-Pssession) -scriptblock {Get-Mailbox -resultsize unlimited | select-object -property Displayname,Identity,PrimarySMTPAddress}
Microsoft Module: RobustCloudCommand – Microsoft created a module that can be used, originally it used to be a script. The module is designed to stay under the throttling limitations imposed by Microsoft. The module keeps an eye on the amount of commands issued, the amount of time or data collected, throttling errors, and so on. The module will tear down and rebuild the PowerShell session when needed and pickup where the script left off. AND one of the coolest things is that it supports Modern Auth and will renew your OAUTH tokens automatically. Let those big scripts fly! The only issue I see is that its limited in complex PowerShell commands. However if you want to run a single command, such as adding a BlockEverything Authentication Policy for every single one my theoretical 400K users, the workhorse below will do the trick
Install-Module -Name RobustCloudCommand #https://www.powershellgallery.com/packages/RobustCloudCommand
$users = Import-csv C:\temp\AllMailboxes.csv
Start-RobustCloudCommand -recipients $Users -logfile C:\temp\out.log -ScriptBlock {Get-user $input.userprincipalname -AuthenticationPolicy BlockEverything}
Manage Quarantined Messages in the Security and Compliance Center via PowerShell
Scenario: You want to start managing the Microsoft Online Quarantine via PowerShell. Its about time! The Microsoft GUI doesn’t play nice with wildcard queries.
First, you need to have the Exchange Online PowerShell Module, or another PS method to connect-IPPSSession.
Once you are connected to the Security and Compliance Center via PowerShell, you can run commands similar to this:
Get Quarantined Emails
Get-QuarantineMessage -StartReceivedDate 1/14/2021 -EndReceivedDate 1/16/2021 | FL
Get-QuarantineMessage -StartReceivedDate 1/14/2021 -EndReceivedDate 1/16/2021 -Type transportrule | Where SenderAddress -like *@gmail.com
Loop with Pages for Quarantined Messages
$P = 1
$messages = $null
do
{
Write-Host “Message Trace – Page $P…”
$temp_Messages = Get-QuarantineMessage -StartReceivedDate 1/15/2021 -EndReceivedDate 1/16/2021 -Type transportrule -page $p -pagesize 50
$P++
$Messages += $temp_Messages
}until ($temp_Messages -eq $null)
Release Quarantined Emails
Get-QuarantineMessage -StartReceivedDate 1/14/2021 -EndReceivedDate 1/16/2021 -Type transportrule | Where SenderAddress -like *@gmail.com | Release-QuarantineMessage -ReleaseToAll