0

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"
4
  • 1
    That's a lot of code to digg through. I'd recommend to start either learning how to debug or how to create advanced functions with the ability to run remotely. Commented Sep 1, 2020 at 1:21
  • Yes, I will find out some ways to make it work and then update it here in smaller code sections. Commented Sep 1, 2020 at 5:04
  • 1
    I think the param() block should be the first thing inside a scriptblock. Move line Write-Host "Processing on server $($_)" -ForegroundColor Yellow below the param block. Commented Sep 1, 2020 at 10:59
  • Yes, that does make sense. many thanks, @Theo for the enlightenment. Commented Sep 15, 2020 at 7:36

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.