So my issue is that this script will run fine the first time but if I try running it again, the PSSessions are still active despite the
Get-PSSession | Remove-PSSession
lines. I've tried other methods like calling the computernames or instanceIDs but still won't close them. I'm not sure why the sessions aren't closing but it's the last thing that is keeping this script from working correctly.
Also this is made from the Microsoft article here: https://support.microsoft.com/en-us/help/2956029/migrationpermanentexception-cannot-find-a-recipient-that-has-mailbox-g
#Exchange session for EOL
function EOLExchange-Session {
Write-Host "Importing Exchange Scripting Module.....please wait a few seconds"
Write-Host "NOTE: Login with your username@aklsj.com credentials for Office 365" -ForegroundColor red -BackgroundColor white
pause
$counter = 0
while ($counter -lt 3) {
try {
$EOLPSSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell-liveid?DelegatedOrg=yalldontneedtoknow.com -Authentication Basic -AllowRedirection -Credential $UserCredential -ea stop
write-host "success"
$counter = 10
}
catch {
write-host "failed"
$counter++
if ($counter -ge 3) {
print "Too many attempts"
exit
}
}
}
Import-PSSession $EOLPSSession -AllowClobber -DisableNameChecking -CommandName Get-Mailbox, Set-Mailbox
$SessionID = $EOLPSSession.InstanceId
Write-Host "-------------Instance ID = " $PSSession.InstanceId
Write-Host "-------------Exchange-Session ID = " $SessionID
$SessionID
}
#Exchange session for On-Prem
function OPExchange-Session {
add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction Stop
#Write-Host "Importing Exchange Scripting Module.....please wait a few seconds"
#Connect to Exchange using Remote Shell <-- allows Exchange commands in this script
$OPPSSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://mindyabusiness.com/PowerShell/ -Authentication Kerberos -AllowRedirection
Import-PSSession $OPPSSession -AllowClobber -DisableNameChecking -CommandName Get-RemoteMailbox, Set-RemoteMailbox
$SessionID = $OPPSSession.InstanceId
#Write-Host "-------------Instance ID = "$PSSession.InstanceId
#Write-Host "-------------Exchange-Session ID = "$SessionID
$SessionID
}
Function End-Script($SessionID, $f_runtype) {
Write-Host "Log File: $LogFile"
Write-Host ""
if ($SessionID -ne $null) {
$s = Get-PSSession -InstanceId $SessionID
Remove-PSSession -Session $s
}
if((Get-Content $LogFile) -eq $Null) {
Remove-Item $LogFile
} else {
#Set Log File to Read Only
Set-ItemProperty -Path $LogFile -Name IsReadOnly -Value $true
}
Write-Host "Script Complete" -ForegroundColor Gray
Read-Host "Press enter to close the script"
exit
}
Function SyncADConnect {
$s = New-PSSession -computerName server
Invoke-Command -Session $s -Scriptblock {Start-ADSyncSyncCycle -PolicyType Delta}
Remove-PSSession $s
End-Script
}
#Removes any PSSessions before running
Get-PSSession | Remove-PSSession
#Find current path script is executing from
$ScriptPath = $PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
$ScriptPath = $ScriptPath + "\"
#Setup Log File
$LogPath = $ScriptPath + "Logs\"
$LogFilename = "SetExchangeGUID_$((Get-Date).ToString('yyyy-MM-dd_hh-mm-ss')).log"
$LogFile = $LogPath + $LogFilename
New-Item -Path "$LogFile" -ItemType File
Write-Host "Checking Domain Admin Permissions...."
$CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$WindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($CurrentUser)
#Make sure user is a domain admin
if(!($WindowsPrincipal.IsInRole("Domain Admins")))
{
Write-Host "You must be logged in as a Domain Admin to run this script" -ForegroundColor Red
End-Script
} else {
Write-Host "Domain Admin permissions detected, please wait....."
}
$today = Get-Date -Format yyyy-MM-dd_hh-mm-ss
$msg = "Run on " + $today + ". Run by " + $env:username
$msg | out-file $LogFile -Append
#Clear-Host
$CloudMailbox = Read-Host "Enter the identity of the cloud mailbox"
Write-Host "Connecting to EOL"
EOLExchange-Session
$SessionID = $EOLPSSession.InstanceId
Write-Host $SessionID
#Fetches EOL ExchangeGUID and trims to just the GUID
$TempCloudGUID = Get-Mailbox $CloudMailbox | Format-List ExchangeGUID | Out-String
$CloudGUID = $TempOnPremGUID.Substring(19).Trim()
#Clear-Host
Write-Host "The EOL GUID is $CloudGUID"
pause
Write-Host "Connecting to On-Prem"
OPExchange-Session
#Fetches ExchangeGUID and trims to just the GUID
$TempOnPremGUID = Get-RemoteMailbox $CloudMailbox | Format-List ExchangeGUID | Out-String
$OnPremGUID = $TempOnPremGUID.Substring(19).Trim()
#Checks if GUID is all zeros
#$ZeroGUID = "00000000-0000-0000-0000-000000000000"
#if ($OnPremGUID -eq $ZeroGUID) {
#Write-Host "The value isn't stamped on the on-premises remote mailbox. Ending script"
#End-Script
#} else {
#Write-Host $CloudMailbox "On-prem GUID is" $OnPremGUID
#}
#Clear-Host
Write-Host "EOL GUID is $CloudGUID"
Write-Host "On-prem GUID is $OnPremGUID"
if ($CloudGUID -eq $OnPremGUID) {
Write-Host "Exchange GUIDs already match, ending script."
End-Script
} else {
$confirmation = Read-Host "The GUIDs are different, would you like to set the EOL GUID to be the same as On-Prem?"
if ($confirmation -eq 'y') {
Set-RemoteMailbox $CloudMailbox -ExchangeGUID $CloudGUID
$msg = "$CloudMailbox has been changed to use $CloudGUID in EOL and On-Prem"
$msg | out-file $LogFile -Append
Write-Host "GUID for $CloudMailbox has been set. Syncing ADSyncClcye and ending script"
Get-PSSession | Remove-PSSession
SyncADConnect
}
else {End-Script}
}
No reason to do this from scratch. There are already tools/addons to do this for you.
See these:
Connect to all Office 365 Services PowerShell (Supports MFA too)
Using our All-in-One PowerShell script, you can connect to all Office 365 Services using a single cmdlet. It supports both MFA and non-MFA account -Exchange Online -Azure AD -SharePoint Online -Skype for Business Online -Security & Compliance Center -Teams
https://jaapwesselius.com/2013/07/21/ise-remote-powershell-and-exchange-2013
# in the Microsoft.PowerShellISE_profile.ps1 file, add the following contents:
$psISE.CurrentPowerShellTab.AddOnsMenu.SubMenus.Add(
"Connect to Exchange @ Contoso", {
$ExSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri 'http://exserver.contoso.com/PowerShell/' -Authentication Kerberos
Import-PSSession $ExSession
},
"Control+Alt+1"
)
$psISE.CurrentPowerShellTab.AddOnsMenu.SubMenus.Add(
"Connect to Exchange On-Premise", {
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
. $env:ExchangeInstallPath\bin\RemoteExchange.ps1
Connect-ExchangeServer –auto
},
"Control+Alt+2"
)
$psISE.CurrentPowerShellTab.AddOnsMenu.SubMenus.Add(
"Connect to Exchange Online", {
$o365Cred = Get-Credential
$o365Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri 'https://ps.outlook.com/powershell/' -Credential $o365Cred -Authentication Basic -AllowRedirection
Import-PSSession $o365Session
},
"Control+Alt+3"
)
As for this...
Get-PSSession | Remove-PSSession
... though it should work, I've often had this be a bit quirky, with forcing a loop.
Get-PSSession | ForEach {Remove-PSSession -Id $PSItem.Id}