connect to exchange management shell

Roger Roger 7,301 Reputation points
2025-09-14T20:49:35.9166667+00:00

Hi All,

Previously, I was running Exchange 2016, and my scheduled script worked fine because the VM had the Exchange 2016 Management Tools installed.

Now, I have upgraded from Exchange 2016 to Exchange 2019 and uninstalled the Exchange 2016 management tools. Since I do not want to install the Exchange 2019 management tools, I want my script to connect remotely to the Exchange 2019 Management Shell using PowerShell remoting. Please guide me.

My script(Batch file) runs once every 6 hours via Task Scheduler.

Old script (worked in Exchange 2016 with management tools installed)

#This is my batch file, this will call script1.ps1

DEL /Q C:\myscripts\batch1.csv

%SystemRoot%\system32\WindowsPowerShell\v1.0\PowerShell.exe -PSConsoleFile "C:\Program Files\Microsoft\Exchange Server\V15\Bin\ExShell.psc1" -Command ". 'C:\Scripts\Exchange\script1.ps1'"

New approach (for Exchange 2019 without management tools)

#This is my batch file,this will call script1.ps1

@echo off
REM Delete old CSV
DEL /Q "C:\myscripts\batch1.csv"
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\Exchange\script1.ps1"

Below is my script1.ps1 which will connect to exchange management shell. i have 3 exchange servers. the account which i am using in task scheduler has the rights to connect to exchange management shell, will this script use the same account?

param([string]$UPN)
$Error.Clear()
# List of Exchange 2019 servers
$Servers = @(
    "exch01.contoso.com",
    "exch02.contoso.com",
    "exch03.contoso.com"
)
if ($UPN) {
    $UserCredential = Get-Credential -Credential $UPN
}
$Connected = $false
foreach ($Server in $Servers) {
    if (Test-Connection -ComputerName $Server -Quiet -Count 2) {
        try {
            $Session = New-PSSession -ConfigurationName Microsoft.Exchange `
                                     -ConnectionUri "http://$Server/PowerShell/" `
                                     -Authentication Kerberos `
                                     -Credential $UserCredential
            if ($Session) {
                Import-PSSession $Session -DisableNameChecking
                . 'C:\Scripts\Exchange\script1.ps1'
                $Connected = $true
                break   # stop after first successful connection
            }
        }
        catch {
            # log failure if needed
        }
    }
}
if (-not $Connected) {
    Write-Error "No Exchange PowerShell session is available"
}

Exchange | Exchange Server | Management
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Vergil-V 3,675 Reputation points Microsoft External Staff Moderator
    2025-09-15T01:33:49.94+00:00

    Hi @Roger Roger 
    Thank you for reaching out to Microsoft Learn Q&A!   
    Based on your description, I understand you're looking to confirm whether the account used in Task Scheduler is the same one being referenced in your Exchange Remote PowerShell script. 

    As a forum moderator, I don’t have access to a dedicated testing environment to replicate specific user scenarios. However, driven by our mission to support the community, I’ve conducted some research and I’m happy to share insights that I hope will be helpful. 

    According to the following Microsoft Learn article, your script1.ps1 should run successfully as a standalone script in an interactive session: Connect to Exchange servers using remote PowerShell | Microsoft Learn 

    However, when used in combination with Task Scheduler, the Get-Credential step may not be optimal for automation. From my research, if you do not explicitly specify a user in the -Credential parameter, PowerShell defaults to the current user. This typically aligns with the account configured in Task Scheduler, assuming it has the necessary permissions. 

    undefined

    You might consider using a static credential input instead of prompting for credentials dynamically. Please note that while this method can be useful for testing, it’s not recommended for production use due to privacy and security concerns, as credentials may be exposed.  

     I sincerely hope this information partially clarifies your situation and assists you in planning your solution.  Please know that while our initial response might not resolve the issue right away, your input is incredibly valuable. With a bit more detail, we’ll work together to find the best solution for you.  


    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".         

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread 


  2. Roger Roger 7,301 Reputation points
    2025-09-15T04:49:23.5566667+00:00

    lets say i have a service account and i have encrypted the creds in the below format. how can i use it in the script.ps1

    $Key = "C:\Scripts\svc_account"

    $Uname = "svc_account(at)contoso(dot)com"

    $Pass = cat $Key | ConvertTo-SecureString

    $Credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $Uname, $Pass

    0 comments No comments

  3. Roger Roger 7,301 Reputation points
    2025-09-15T06:05:36.92+00:00

    will the below work, can anyone test it please

    #This is my batch file,this will call script1.ps1 
    @echo off REM Delete old CSV 
    DEL /Q "C:\myscripts\batch1.csv" 
    powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\Exchange\script1.ps1"
    
    param([string]$UPN)
    
    # Start transcript logging
    $file = "C:\Scripts\Logs\ExchangeConnection.log"
    Start-Transcript $file -Force
    
    $Error.Clear()
    
    # -----------------------------
    # Credentials
    # -----------------------------
    $Key   = "C:\Scripts\svc_account"
    $Uname = "svc_account(at)contoso(dot)com"   # Use normal @ not (at) for actual login
    $Pass  = Get-Content $Key | ConvertTo-SecureString
    $Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Uname, $Pass
    
    # If UPN is passed, use interactive credentials instead
    if ($UPN) {
        $UserCredential = Get-Credential -Credential $UPN
    }
    else {
        $UserCredential = $Credentials
    }
    
    # -----------------------------
    # Exchange Servers
    # -----------------------------
    $Servers = @(
        "exch01.contoso.com",
        "exch02.contoso.com",
        "exch03.contoso.com"
    )
    
    $Connected = $false
    
    foreach ($Server in $Servers) {
        if (Test-Connection -ComputerName $Server -Quiet -Count 2) {
            try {
                $Session = New-PSSession -ConfigurationName Microsoft.Exchange `
                                         -ConnectionUri "http://$Server/PowerShell/" `
                                         -Authentication Kerberos `
                                         -Credential $UserCredential
                if ($Session) {
                    Import-PSSession $Session -DisableNameChecking
                    . 'C:\Scripts\Exchange\script1.ps1'
                    $Connected = $true
                    break   # stop after first successful connection
                }
            }
            catch {
                Write-Warning "Failed to connect to $Server"
            }
        }
    }
    
    if (-not $Connected) {
        Write-Error "No Exchange PowerShell session is available"
    }
    
    Stop-Transcript
    
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.