如何使用Invoke-Command作为域管理员在远程服务器上执行命令?

时间:2020-09-01 00:26:15

标签: powershell

我正在尝试修改一个脚本,该脚本在手动在每台服务器上执行时可以工作以生成DFS复制,然后发送电子邮件,因此可以从一个位置执行一次,然后远程连接到每台服务器。

调用命令:

$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
    }
}

这是我收到的错误:

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

以前可以使用的实际Powershell脚本,但是必须在每个服务器RDP会话中手动执行:

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 = "boss@it.com";
$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"

1 个答案:

答案 0 :(得分:1)

Theo是正确的,Param()代码需要首先在脚本块中进行。您可以在这里找到有关脚本块的更多信息:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_script_blocks?view=powershell-7