在 PS 脚本中处理 PS 会话

Handling PSSessions in PS script

所以我的问题是这个脚本第一次 运行 没问题,但如果我再次尝试 运行,PSSessions 仍然处于活动状态,尽管

获取PSSession |删除 PSSession

行。我尝试了其他方法,例如调用计算机名或实例 ID,但仍然无法关闭它们。我不确定为什么会话没有关闭,但这是阻止此脚本正常工作的最后一件事。

这也是从微软的文章中得到的: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}
}

没有理由从头开始。已经有 tools/addons 人为您做这件事。

查看这些:

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://gallery.technet.microsoft.com/PowerShell-Script-to-4081ec0f/file/225256/1/ConnectO365Services.ps1

https://blog.rmilne.ca/2015/02/02/using-exchange-powershell-remoting-with-integrated-scripting-environmentise

https://jaapwesselius.com/2013/07/21/ise-remote-powershell-and-exchange-2013

Adding Exchange Shell items to PowerShell ISE

# 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"
)

至于这个...

Get-PSSession | Remove-PSSession

...虽然它应该可以工作,但我经常让它有点古怪,强制循环。

Get-PSSession | ForEach {Remove-PSSession -Id $PSItem.Id}