Senior Systems Engineer
Senior Systems Engineer

Reputation: 1153

How to execute command on remote server using Invoke-Command as Domain Administrator?

I am trying to modify a script that used to work when executed on each of the servers manually to generate the DFS replication then send an email, so it can be executed once from one location then remotely connect to each and every server.

Invoke-Command:

$ComputerName = Get-DfsrMember | Select-Object -ExpandProperty ComputerName -Unique | Sort-Object

$ComputerName | ForEach-Object {
    Try {
        $session = New-PSSession -ComputerName $_ -ErrorAction Stop
        Invoke-Command -ErrorAction Stop -Session $session -ScriptBlock {
          ## Script body starts here....
            Write-Host "Processing on server $($_) `n" -ForegroundColor Yellow
            Param (
             [String[]]$ReplicationGroupList = ("")
            )
         ....

        }
    }
    Catch [System.UnauthorizedAccessException] {
        Write-Warning "You do not have the proper access to this system!"
        Break
    }
    Catch [System.Runtime.InteropServices.COMException] {
        Write-Warning "Communications Exception occurred!"
        Break
    }
}

This is the error I have received:

The term 'Param' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:7 char:9
+         Invoke-Command -ErrorAction Stop -Session $session -ScriptBlo ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Param:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
    + PSComputerName        : PRDDC01-VM

The actual Powershell script that used to be working, but must be manually executed in each of the server RDP session:

Param (
    [String[]]$ReplicationGroupList = ("")
)

$RGroups = Get-WmiObject  -Namespace "root\MicrosoftDFS" -Query "SELECT * FROM DfsrReplicationGroupConfig"
#If replication groups specified, use only those.
if ($ReplicationGroupList) {
    $SelectedRGroups = @()
    foreach ($ReplicationGroup IN $ReplicationGroupList) {
        $SelectedRGroups += $rgroups | Where-Object { $_.ReplicationGroupName -eq $ReplicationGroup }
    }
    if ($SelectedRGroups.count -eq 0) {
        Write-Error "None of the group names specified were found, exiting"
        exit
    }
    else {
        $RGroups = $SelectedRGroups
    }
}

$ComputerName = $ENV:ComputerName
$Succ = 0
$Warn = 0
$Err = 0
Start-Transcript -path "$([Environment]::GetFolderPath("Desktop"))\dfsr1.txt"
foreach ($Group in $RGroups) {
    $RGFoldersWMIQ = "SELECT * FROM DfsrReplicatedFolderConfig WHERE ReplicationGroupGUID='" + $Group.ReplicationGroupGUID + "'"
    $RGFolders = Get-WmiObject -Namespace "root\MicrosoftDFS" -Query  $RGFoldersWMIQ
    $RGConnectionsWMIQ = "SELECT * FROM DfsrConnectionConfig WHERE ReplicationGroupGUID='" + $Group.ReplicationGroupGUID + "'"
    $RGConnections = Get-WmiObject -Namespace "root\MicrosoftDFS" -Query  $RGConnectionsWMIQ
    foreach ($Connection in $RGConnections) {
        $ConnectionName = $Connection.PartnerName#.Trim()
        if ($Connection.Enabled -eq $True) {
            if (((New-Object System.Net.NetworkInformation.ping).send("$ConnectionName")).Status -eq "Success") {
                foreach ($Folder in $RGFolders) {
                    $RGName = $Group.ReplicationGroupName
                    $RFName = $Folder.ReplicatedFolderName

                    if ($Connection.Inbound -eq $True) {
                        $SendingMember = $ConnectionName
                        $ReceivingMember = $ComputerName
                        $Direction = "inbound"
                    }
                    else {
                        $SendingMember = $ComputerName
                        $ReceivingMember = $ConnectionName
                        $Direction = "outbound"
                    }

                    $BLCommand = "dfsrdiag Backlog /RGName:'" + $RGName + "' /RFName:'" + $RFName + "' /SendingMember:" + $SendingMember + " /ReceivingMember:" + $ReceivingMember
                    $Backlog = Invoke-Expression -Command $BLCommand

                    $BackLogFilecount = 0
                    foreach ($item in $Backlog) {
                        if ($item -ilike "*Backlog File count*") {
                            $BacklogFileCount = [int]$Item.Split(":")[1].Trim()
                        }
                    }

                    if ($BacklogFileCount -eq 0) {
                        $Color = "white"
                        $Succ = $Succ + 1
                    }
                    elseif ($BacklogFilecount -lt 10) {
                        $Color = "yellow"
                        $Warn = $Warn + 1
                    }
                    else {
                        $Color = "red"
                        $Err = $Err + 1
                    }
                    Write-Output "$BacklogFileCount files in backlog $SendingMember->$ReceivingMember for $RGName"

                } # Closing iterate through all folders
            } # Closing  If replies to ping
        } # Closing  If Connection enabled
    } # Closing iteration through all connections
} # Closing iteration through all groups
Write-Output "$Succ successful, $Warn warnings and $Err errors from $($Succ+$Warn+$Err) replications."
Stop-Transcript

$file = "$([Environment]::GetFolderPath("Desktop"))\dfsr1.txt"

get-content $file |
Select-Object -Skip 18 |
set-content "$file-temp"
Move-Item "$file-temp" $file -Force

$emailrecipients = "[email protected]";
$emailbody = Get-Content -Path "$([Environment]::GetFolderPath("Desktop"))\dfsr1.txt" -Raw

Send-MailMessage -to $emailrecipients -smtpserver smtp.domain.COM -from "$env:COMPUTERNAME@$env:userdnsdomain" -subject "DFSR Report for $(get-date -format dd/MM/yyyy) from $env:COMPUTERNAME" -body $emailbody;

Remove-Item "$([Environment]::GetFolderPath("Desktop"))\dfsr1.txt"

Upvotes: 0

Views: 345

Answers (1)

catherinemohan
catherinemohan

Reputation: 371

Theo is correct, the Param() code needs to be first thing in the script block. You can find more information about script blocks here: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_script_blocks?view=powershell-7

Upvotes: 1

Related Questions