ForEach Installed PowerShell Module Thanos Wipe.

ForEach Installed PowerShell Module Thanos Wipe.

In recent times I have been playing with a number of PowerShell modules and now decided to have a bit of a clean up or in the world of PowerShell and Marvel Install-Thanos

Image result for thanos

This process couldnt be any easier if I try,


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$Array = @(Get-InstalledModule)

   Foreach ($Module in $Array)
   {
     $ModuleCheck = Get-InstalledModule -name $Module.Name -ErrorAction SilentlyContinue  

     if ($ModuleCheck) {
     Write-Host 'Info: Detected an installation of the',$Module.Name,'Module' -ForegroundColor Green
     $Module = Get-Module -Name $Module.Name -ListAvailable
       
     # Identify modules with multiple versions installed
     Write-Host 'Info: Removing',$Module.Name,'Module' -ForegroundColor Yellow
     Uninstall-Module -Name $Module.Name -Force
   }
   }

And just like magic, all your PowerShell Modules should disappear like the Spiderman.

Regards
The Author – Blogabout.Cloud

Changing Window Updates setting using PowerShell

Changing Window Updates setting using PowerShell

In this post, I will look at how to modify the required Registry Keys for Windows Server 2012R2 / 2016 Update settings using PowerShell. PowerShell is one of the gems within Microsoft and enables us to work with systems without the help of a GUI.

Windows always looks at registry keys located in the following hive:
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU

Typically there is a key named ‘NoAutoUpdate’ with a value in the range 2-5, and have the following meaning:

– 1 = Disable Updates – Only supported on Windows 2012 R2.
– 2 = Notify before download.
– 3 = Automatically download and notify of installation.
– 4 = Automatically download and schedule installation. Only valid if values exist for ScheduledInstallDay and ScheduledInstallTime.
– 5 = Automatic Updates is required and users can configure it.

But if there is a ‘NoAutoUpdate’ key with the value of ‘1’, no updates will be processed by Windows.

You can change the registry key with the help of Powershell directly:

1
Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU -Name NoAutoUpdate -Value 3

Regards
The Author – Blogabout.Cloud

Say goodbye to your legacy PSGallery modules with Get-InstalledModuleUpdate.ps1

Say goodbye to your legacy PSGallery modules with Get-InstalledModuleUpdate.ps1

Working as a Microsoft Cloud Consultant sometimes its hard to keep update to all the latest release of the required PowerShell modules installed on your client machine. Would it be nice if there was a script that took all that pain away?

Say hello to Get-InstalledModulesUpdate.ps1 script

Image result for groot wave

This script is based off my Microsoft Teams Detection script but instead of looking at just that module. I am grabbing all your installed PowerShell module and checking each one against the PSGallery

Module checking

As you can see from my screen shot the script has looked at each modules installed on my client machine and compared to the online version. If a legacy module was detected the update process would start to remove the old version and install the latest from the gallery.

This script is available via my Github or via this site.

Download

Get-InstalledModulesUpdates.ps1 (12 downloads)

Change Log

Version 1.0 – Features

  • Initial release

Version 1.1 – Features

  • Minor updates to code structure

Version 1.2

  • Minor updates to code structure

Version 1.3

  • Minor updates to code structure
  • Transcript of the changes made and dumped to Desktop.

Regards

The Author – Blogabout.Cloud

Working with Variables located in PowerShell Functions

Working with Variables located in PowerShell Functions

I have been recently working on updating a number of my PowerShell scripts and ran into an issue where my variables were unavailable within a function. The resolution for this is making the variables globally available to all the function(s) that are contained within your script.

So, as you can see below. I have configured my script blocks into Functions and converted the Parameter variables into $Global: variables. This will allow the Get-MailMessage function to use the $Global: variables within its own function

Without $Global:
With $Global:

However, there is one more step required to ensure that the variables can use the globally defined variables. I have a configure region within my script that contains all my defined variables and in here I have put for example $Global:Variable = $Global:Variable

$Global:Variables = $Global:Variables

As you can see from above image the variables located in New-MailMessage function are not highlighted in yellow.

Tools of the trade

The reason for the highlighted variables within my script, I use a tool called PowerShell ISE http://www.powertheshell.com. There is a slight cost but well worth it if you are regularly building scripts.

Regards

The Author – Blogabout.Cloud

The Great Wall in Microsoft Teams – Information Barrier in Preview

The Great Wall in Microsoft Teams – Information Barrier in Preview

Another great feature now become available in Microsoft Teams Preview – Information Barrier. This enables organization to prevent communicate between Teams within their own Office 365 tenant. The information barrier groups cannot be applied across tenants and using bots to add users is not supported in version 1. Information barrier policies also prevent lookups and discovery. This means that if you attempt to communicate with someone you should not be communicating with, you will not find that user in the people picker.

You might want to use information barriers in situations like these:

  • A team must be prevented from communicating or sharing data with a specific other team.
  • A team must not communicate or share data with anyone outside of the team.

In order to manage the Information Barrier policy you will need to use the Security and Compliance Centre (SCC) PowerShell cmdlets

The information barrier features is in private preview. When these features are generally available, they’ll be included in the following subscriptions;

  • Microsoft 365 E5
  • Office 365 E5
  • Office 365 Advanced Compliance
  • Microsoft 365 E5 Compliance

Microsoft Teams is firmly becoming the powerhouse that was sold at its initial launch and I can only this product becoming adopted a lot more by organisations

Regards

The Author – Blogabout.Cloud

Microsoft Teams module now in GA

Microsoft Teams module now in GA

Its been a long road but Microsoft Teams PowerShell module version 1.0.0 is now available in GA. Microsoft has been working very hard in creating this module and have removed/introduction features into this release. So lets have a look at what we now can and cannot do with Microsoft Teams

So what’s removed?

So Microsoft have removed the following cmdlets

  • Get-TeamFunSettings
  • Get-TeamGuestSettings
  • Get-TeamMemberSettings
  • Get-TeamMessagingSettings
  • Set-TeamFunSettings
  • Set-TeamGuestSettings
  • Set-TeamMemberSettings
  • Set-TeamMessagingSettings

But do not fear, as the same functionality of these cmdlets have been integrated into Get-Team and Set-Team.

So what’s new?

  • Connect-MicrosoftTeams allows you to specify a Teams Government Environment (-TeamsEnvironmentName) that your organization is homed in.
  • Get-Team allows you to specify new filter and selection criteria to identify specific teams based off of new criteria, including the Visibility or Archived state of the teams.

So its time to start playing with the Teams module and seeing what interesting scripts can be generated.

Please Note: It is recommended to uninstall any previous version you may have installed. So check out this previous blog post i created

http://www.blogabout.cloud/2018/09/240/


Regards
The Author – Blogabout.Cloud

The pain in the a** that is special characters. Understanding what is and isnt supported when migrating to the Microsoft Cloud.

The pain in the a** that is special characters. Understanding what is and isnt supported when migrating to the Microsoft Cloud.

Related image

So in recent months, I have been working a number of large organisation that have issues with special characters that are affecting their migration to the Microsoft Cloud. Yes, I IDFix does an excellent job of correcting a lot of the issues. However, in recent time I have been rolled into customer sites to troubleshoot and report on special characters contained in Distribution Lists and Shared Mailboxes which cannot be migrated to Exchange Online.

What special characters are supported in Office 365?

So first of all, what is and is not supported. The below table gives an excellent break down what the character can be supported in UserNames, Password and Email Addresses.

Allowed In
Character NameCharacterUser NamePasswordEmail Address
Accent`NoYesNo
Ampersand&NoYesNo
Angle Brackets< >NoYesNo
ApostropheNoYesYes***
Asterisk*NoYesNo
At Symbol@NoYesNo
Backslash\NoYesNo
Braces[ ]NoYesNo
Brackets{ }NoYesNo
Circumflex^NoYesNo
Colon:NoYesNo
Comma,NoYesNo
Dollar Sign$NoYesNo
Equal Sign=NoYesNo
Exclamation Point!NoYesNo
HyphenYes*YesYes*
Number Sign#NoYesNo
Parentheses( )NoYesNo
Percent Symbol%NoYesNo
Period.Yes*YesYes*
Pipe|NoYesNo
Plus Sign+NoYesNo
Question Mark?NoYesNo
Quotation MarkNoYesNo
Semicolon:NoYesNo
Forward Slash/NoYesNo
Tilde~NoYesNo
Underscore_Yes**YesYes**
Uppercase Letters (A-Z)A-ZYesYesYes
Lowercase Letters (a-z)a-zYesYesYes
Numerals (0-9)0-9YesYesYes

In order to test for the special characters above I have created the following script


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
cls
 $array = @('~', '!', '#', '$', '%', '^', '&amp;', '(', ')', '-', '.+', '=', '}', '{', '\', '/', '|', ';', ',', ':', '&lt;', '>', '"')
 $samaccountarray = @('[', '\', '"', '|' , ',' , '/', ':', '&lt;', '>', '+', '=', ';', ']')
 foreach ($char in $array) {
 Write-Host "Please Wait... Detecting",$char," in samaccountname" -ForegroundColor Yellow
 $objects = Get-distributiongroup
 foreach ($object in $Objects)
 {
 try {
  if ($object.SamAccountName -like "*$char*")
 {
 Write-Host "Special Character",$char,"detected in SamAccountName",$object.samaccountname -ForegroundColor Red
 
 }
 else
 {
 #Write-Host "Special Character",$char," not detected in " $object.UserPrincipalName
 }
 }
 catch
 {
 Write-Host "Great News!! we was unable to detect",$char,"in samaccountnames for all Distribution List" -ForegroundColor Green
 }
 }
 }
Get-SpecialCharacters (24 downloads)

If you are interested in understanding what IDFix does and what special characters are not supported, please see this link

https://docs.microsoft.com/en-gb/office365/enterprise/prepare-for-directory-synchronization?redirectSourcePath=%252fen-us%252farticle%252fPrepare-to-provision-users-through-directory-synchronization-to-Office-365-01920974-9e6f-4331-a370-13aea4e82b3e

Regards

The Author – Blogabout.Cloud

Get Disabled Users who have an Exchange Mailbox with PowerShell

Get Disabled Users who have an Exchange Mailbox with PowerShell

If there’s one thing most IT department are not great at its removing Exchange Mailboxes for Disabled Users. So here’s a quick Powershell win to determine who within your Exchange organisation has a mailbox and a disabled AD account.

On-Premises Users


1
2
3
4
5
6
7
8
9
$Mailboxes = Get-Mailbox | where {$_.RecipientTypeDetails -eq 'UserMailbox'}
$Disabled = @()

Foreach ($Mailbox in $Mailboxes) {
    if((Get-ADUser -Identity $Mailbox.SamAccountName).Enabled -eq $False){
        $Disabled += Get-MailboxStatistics $Mailbox.SamAccountName | Select -Property DisplayName,TotalItemSize
    }    
}
$Disabled | Export-Csv -Path $env:userprofile\desktop\DisabledADUserwithMailbox.csv -NoTypeInformation

Cloud Users


1
2
3
4
5
6
7
8
9
10
11
Connect-MsolService
 
  $Mailboxes = Get-Mailbox | Where-Object {$_.RecipientTypeDetails -eq 'UserMailbox'}
  $Disabled = @()

  Foreach ($Mailbox in $Mailboxes) {
    if((Get-msolUser -userprincipalname $Mailbox.userprincipalname).Enabled -eq $False){
        $Disabled += Get-MailboxStatistics $Mailbox.userprincipalname | Select-Object -Property DisplayName,TotalItemSize
    }    
  }
  $Disabled | Export-Csv -Path $env:userprofile\desktop\DisabledAzureADUserwithMailbox.csv -NoTypeInformation

Regards

The Author – Blogabout.Cloud

Method invocation failed because [System.Management.Automation.PSObject] doesn’t contain a method named ‘op_Addition’.

Method invocation failed because [System.Management.Automation.PSObject] doesn’t contain a method named ‘op_Addition’.

While constructing a PowerShell script for gathering information about Distribution Lists within a customers environment, I ran into the following error

Method invocation failed because [System.Management.Automation.PSObject] doesn’t contain a method named ‘op_Addition’. 

ERROR!!!
1

This error was being generated by a missing array within my PowerShell code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Call Distribution Lists
$dist = @(Get-DistributionGroup -resultsize unlimited)

# Start Transcript
Start-Transcript -Path $env:USERPROFILE\desktop\DLsandMember.txt

# Report on Distribution List
foreach ($dl in $dist)
{
 
  $count =@(Get-DistributionGroup $dl.samaccountname).count
  $report = New-Object -TypeName PSObject
  $report | Add-Member -MemberType NoteProperty -Name 'Group Name' -Value $dl.Name
  $report | Add-Member -MemberType NoteProperty -Name 'samAccountname' -Value $dl.samaccountname
  $report | Add-Member -MemberType NoteProperty -Name 'Group Type' -Value $dl.grouptype
  $report | Add-Member -MemberType NoteProperty -Name 'DN' -Value $dl.distinguishedName
  $report | Add-Member -MemberType NoteProperty -Name 'Manager' -Value $dl.managedby
  $report | Add-Member -MemberType NoteProperty -Name 'Member Depart Restriction' -Value $dl.memberdepartrestriction
  $report | Add-Member -MemberType NoteProperty -Name 'Member Join Restriction' -Value $dl.memberjoinrestriction
  $report | Add-Member -MemberType NoteProperty -Name 'PrimarySMTPAddress' -Value $dl.primarysmtpaddress
  $report | Add-Member -MemberType NoteProperty -Name 'EmailAddress' -Value $dl.emailaddresses
  $report | Add-Member -MemberType NoteProperty -Name 'GrantSendOnBehalfto' -Value $dl.GrantSendOnBehalfto
  $report | Add-Member -MemberType NoteProperty -Name 'EmailAddressPolicyEnabled' -Value $dl.EmailAddressPolicyEnabled
  $report | Add-Member -MemberType NoteProperty -Name 'Number of Members' -Value $count
  Write-Host ('INFO: {0} has {1} members' -f $dl.name, ($count))
 
  $reportoutput += $report
}

# Stop Transcript
Stop-Transcript

By adding the following lines to my above script I was able to successful export the required information into an Array and dump out to CSV.


1
2
# Array
$reportoutput=@()

Regards

The Author – Blogabout.Cloud

PowerShell – ForEach do  action X or do Y

PowerShell – ForEach do action X or do Y

PowerShell is one of the greatest tools within any IT Professional toolkit, it enables you to do far more than any GUI available to you today. In my life as a Consultant for a Global Microsoft SI (System Integrator), I face challenges every day where PowerShell has come to the rescue. One of the best cmdlet I use in a lot of script is

ForEach which is the alias name of ForEach-Object

Imagine you need to modify an ExtensionAttribute for your entire organization or grant a permission to a subset of users, ask yourself this? How would I do this in a GUI? and the answer would be “with great difficulty or very time consuming”. This is Foreach-Object comes into play, in the below example I need to modify the PrimarySMTPAddress due to special characters being used

Get-DistributionGroup

In order to correct this, I will be using a source CSV file which contains SamAccountName for the identity of each DistributionList and the correct PrimarySMTPAddress.

Source CSV file

Now for the most important element, the powershell script which will be used to modify the PrimarySMTPAddress. The below script has been designed to achieve the required outcome but also includes the ability to;

  • Be ran using native PowerShell for On-Premises Exchange Servers (2007 through to 2019)
  • Be ran against Exchange Online

So as we can see the Foreach command is being used in the following;

  • For each $row within the $csv which is being imported try and get the distribution list using the column heading SamAccountName
    • If the Identity cannot be found the script will move to the catch
    • If the Identity can be found the script will set the distribution list using the column heading PrimarySMTPAddress
  • The catch is alert if there are any unsuccessful attempts at setting the PrimarySMTPAddress

Simples!!

 Clear-Host
$file = "$env:USERPROFILE\OneDrive\Desktop\groups.csv"
$csv = import-csv -Path $file
region Exchange Module SnapIn
# Exchange 2007
#Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin;
# Exchange 2010
#Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010;
# Exchange 2013/2016
#Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn;
endregion
Transcript
Start-Transcript -Path $env:USERPROFILE\OneDrive\Desktop\Get-DistributionGroup.txt
Foreach ($row in $csv)
{
try {
Get-DistributionGroup -Identity $row.SamAccountName | Set-DistributionGroup -PrimarySmtpAddress $row.PrimarySmtpAddress
Write-Host 'INFO:' ($row.SamAccountName),'Primary SMTP Address has now been modified to',($row.PrimarySmtpAddress) -BackgroundColor Green
}
catch
{
Write-Host 'ERROR:' ($row.SamAccountName),'Primary SMTP Address has not been modified to',($row.PrimarySmtpAddress) -BackgroundColor Red
}
}
Stop-Transcript
Get-DistributionGroup
Image result for meerkat simples gif

I have included Start-Transcript as this will dump out all Write-Host entry whether they was successful or not.

Regards

The Author – Blogabout.Cloud