# How to uninstall PowerShell modules with dependencies within a script.

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.

So,

The following function has made this possible.

Function Uninstall-AllModules
{
[CmdletBinding(SupportsShouldProcess)]
param (
[Parameter(Mandatory = $true)] [string]$TargetModule,
[Parameter(Mandatory = $false)] [string]$Version,
[switch]
$Force )$AllModules = @()

‘Creating list of dependencies…’
$target = Find-Module$TargetModule
$target.Dependencies | ForEach-Object {$AllModules += New-Object -TypeName psobject -Property @{ name = $_.name} }$AllModules += New-Object -TypeName psobject -Property @{ name = $TargetModule}$cnt = 1;
foreach ($module in$AllModules)
{
Write-Host (“[$cnt] – ” + ‘Uninstalling {0} version’ -f$module.name);
$cnt++; try { if ($PSCmdlet.ShouldProcess($module.name, ‘Uninstall’)) { Uninstall-Module -Name$module.name -Force:$Force -ErrorAction Stop; }; } catch { Write-Host (“t” +$_.Exception.Message)
}
}
}

## – Example using -WhatIf parameter:

Regards,

# 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

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

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

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

# 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

Regards

# 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’.

 1

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


12345678910111213141516171819202122232425262728293031# 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.  12# Array$reportoutput=@()



Regards

# 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

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.

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!!

# Is Get-ADUser a bit slow in getting required result? Hello ADSISearcher using PowerShell.

Sometimes Get-ADUser just isn’t enough if you are working thousands upon thousands of AD Objects. In a recent scenario, while resolving an Active Directory Health issue. I needed the ability to be able to compare AD Objects from 2 Active Directory Domains from within a resource forest.

ADSISearcher is a command line driven LDAP Lookup procedure has the ability to query Active Directory. As ADSISearcher looks up Active Directory it enables a faster discovery of the required AD Objects.

#### My scenario

I need to ensure CustomAttribute10 in Child1.domain.com matches CustomAttribute10 in Child2.domain.com, yes I could use Get-ADUser | export-csv but this has proved to take to long and needed a faster solution.

ADSISearcher has proved to reduce the time required to execute this script and dumping out to a transcript file with “,” separating the text allows the information to be imported to excel if required.

 Clear-Host Write-Host "You are currently running Version 1.0" -BackgroundColor DarkGray [string] $Menu = @' ┌─────────────────────────────────────────────────────────────┐ ADSISearcher for CustomAttribute10 Created by @thewatchernode └─────────────────────────────────────────────────────────────┘ '@ Menu$Menu Transcript Start-Transcript -Path "$env:userprofile\Desktop\Child1vsChild2.txt" Start Time$start = [datetime]::Now region Client Array $Child1LDAPFilter = '(objectclass=user)'$PageSize = 1000 $Child1DN = 'DC=child1,DC=domain,DC=com'$Child1SB = 'DC=child1,DC=domain,DC=com' $Child1Searcher = [ADSISearcher]('{0}' -f$child1LDAPFilter) $Child1Searcher.SearchRoot = [ADSI]('GC://{0}' -f$Child1SB) $Child1Searcher.SearchRoot = [ADSI]('GC://{0}' -f$child1DN) $Child1Searcher.PageSize =$PageSize $Child1Objects =$Child1Searcher.FindAll() endregion region Collab Array $Child2SB = 'DC=child2,DC=domain,DC=com'$Child2DN = 'DC=child2,DC=domain,DC=com' endregion region Client vs Collab Foreach($Object in$child1Objects){ $childca10 =$Object.Properties.'customattribute10'   $Child2LDAPFilter = "(objectclass=user,customattribute10=$childca10)"   $child2Searcher1 = [ADSISearcher]("{0}" -f$child2LDAPFilter)   $child2Searcher1.SearchRoot = [ADSI]("GC://{0}" -f$Child2SB)   $child2Searcher1.SearchRoot = [ADSI]("GC://{0}" -f$Child2DN)   $child2Searcher1.PageSize =$PageSize   #$AllObjects1 =$collabSearcher1.FindAll() $nullvalue =$object.Properties.'customattribute10'  if ($nullvalue -eq$null)    {     Write-Host 'INFO, Null Value Found in Child Domain 1,' $Object.Properties.samaccountname -BackgroundColor Red } else { try { ($Object.Properties.'customattribute10' -eq $child2searcher1.Properties.'customattribute10') Write-Host 'Skipping, Attribute match found in Child domain 2 using Child domain 1,'$Object.Properties.samaccountname -ForegroundColor Green     }     catch     {       Write-Host 'INFO, No Attribute match found in Child domain 2 using Child domain 1,' $Object.Properties.samaccountname -BackgroundColor Red } } } endregion Stop Transcript Stop-Transcript End Time$end = [datetime]::Now $resultTime =$end - $start Write-Host ('Execution : {0}Days:{1}Hr:{2}Min:{3}Sec' -f$resultTime.Days, $resultTime.Hours,$resultTime.Minutes, $resultTime.Seconds)  #### Download Get-ADSISearcher (183 downloads) Regards The Author – Blogabout.Cloud # Merging Excel files using PowerShell, yes it can be done. Have you ever worked with Excel files where you wanted to match and compare Columns/Rows? In the past, this has been quite difficult tasks to achieve using the native commands within PowerShell. So have you heard of the PowerShell module ImportExcel? It’s is a PowerShell module that is available on the PowerShell Gallery and introduces a number of functions that allow you to work with Excel files using the good old blue background. From this module we will be working with the following function; • Merge-Worksheet Syntax Merge-Worksheet [-Referencefile] [-Differencefile] [[-WorksheetName] ] [-Startrow ] -Headername [[-OutputFile] ] [[-OutputSheetName] ] [-Property ] [-ExcludeProperty ] [-Key ] [-KeyFontColor ] [-ChangeBackgroundColor ] [-DeleteBackgroundColor ] [-AddBackgroundColor ] [-HideEqual] [-Passthru] [-Show] [-WhatIf] [-Confirm] []  ## Example usage of Function The below shows the Reference and Difference Excel files that are being used in this example. I am going to merge the two excel files based on Column A the EmployeeNumber. During my testing, I have had issues using -HeaderName parameter. In this post I will not be specifying the headings and just modify the output file. # Variables$ref = "$env:USERPROFILE\desktop\test\ref.xlsx"$dif = "$env:USERPROFILE\desktop\test\dif.xlsx"$out = "$env:USERPROFILE\desktop\test\out.xlsx" # Script Block Merge-Worksheet -Referencefile$ref -Differencefile $dif -OutputFile$out -WorksheetName Sheet1 -Startrow 1 -OutputSheetName Sheet1 -NoHeader
﻿


As we can see from below, the output field has organised Column A and aligned the rows

Every useful if you are working with Excel files but only annoying thing is the HeaderName parameter not working.

Regards
# Primary SMTP Addressget-mailbox -resultsize unlimited | where {$_.primarysmtpaddress -like "*@blogabout.cloud"} | Measure-Object # Email Address get-mailbox -resultsize unlimited | where {$_.emailaddress -like "*@blogabout.cloud"} | Measure-Object `