在linux中遠程執行操作我們會用到ssh,在windows中遠程操作需要依賴一個服務“WinRM”,只需要在接收遠程命令的機器上配置WinRM服務即可(默認是開啟的)。
要使用遠程操作之前,首先確認WinRM服務是否開啟
若WinRM服務時關閉狀態,必須使用管理員身份運行命令行工具,才可以執行以下操作
以上都是查看或開啟本機的遠程服務,若要查看被遠程的主機是否開啟遠程操作服務,應使用“Test-WSMan”命令
還差最后一步,也是很重要的一步,在被遠程機器上和遠程機上添加信任后才可執行遠程操作,記住使用管理員權限才可生效,當執行第一條命令時,會彈出一個對話框,選擇“YES”,第一題命令的作用是在本機添加運行任何機器遠程操作,第二個命令重啟WinRM遠程服務,重新讀取配置后才會生效。
Set-Item wsman:\localhost\client\trustedhosts *
Restart-Service WinRM
以上准備工作算是做完了,接下來先遠程連接到一台服務器,然后做一些簡單的操作,與ssh類似。
一、一般操作
PS C:> Enter-PSSession -ComputerName hostname -Credential username
hostname是要連接的服務器名稱,username是登錄服務器的用戶名。
此時會彈出一個對話框,輸入密碼后即可登錄成功,控制台會變成以下內容,表面已經連接到了遠程服務器,此時就可以操作遠程服務器了。
[hostname]: PS C:\Users\username\Documents> #可使用exit退出當前遠程連接
使用上面的方法存在一些問題,那就是需要交互輸入密碼,若要將遠程操作寫入腳本,實現起來就會非常的困難,接下來介紹一種免交互的方法。
首先需要創建遠程連接的認證信息
$username = "\Administrator"
$password = "123456"
$pw = ConvertTo-SecureString -AsPlainText $Password -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$pw
此時$cred就是連接遠程服務器的認證,接下使用“Invoke-Command”命令即可實現遠程操作,-ScriptBlock后面跟的就是要在遠程服務器執行的命令。
Invoke-Command -ComputerName hostname -ScriptBlock{ ls c:\} -Credential $cred
若需要執行腳本,可以用下-FilePath參數,需要注意的是a.ps1(作用是創建c:\a\b目錄)在本機的當前目錄下,並非是遠程機器上的。
PS C:\> Invoke-Command -ComputerName hostname -FilePath .\a.ps1 -Credential $cred
Directory: C:\a
Mode LastWriteTime Length Name PSComputerName
---- ------------- ------ ---- --------------
d----- 12/11/2018 6:24 PM b hostname
Invoke-Command執行的命令中含有本地變量
PS C:\> $a = "a"
PS C:\> $b = ".txt"
PS C:\> Invoke-Command -ComputerName hostname -ScriptBlock{ param($a,$b) echo "1" > c:\a\$a$b} -ArgumentList $a,$b -Credential $Cred
上面的命令作用是:在遠程主機上“c:\a”目錄下將“1”覆蓋到a.txt文件中。
批量操作多台服務器,(前提條件是每天服務器的用戶名密碼一致)
$username = "\Administrator"
$password = "123456"
$pw = ConvertTo-SecureString -AsPlainText $Password -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$pw
現在遠程操作其他服務器
Invoke-Command -ComputerName db1 -ScriptBlock{ ls c:\ } -Credential $cred
Invoke-Command -ComputerName db2 -ScriptBlock{ ls c:\ } -Credential $cred
Invoke-Command -ComputerName db3 -ScriptBlock{ ls c:\ } -Credential $cred
均可以執行成功,不帶-Credential $cred認證參數,照樣可以執行成功,我估計的原因是Invoke-Command執行成功后,將Credential的認證信息緩存到了某個地方,這是再次執行時就去找上次使用的認證去連接,只是估計!。
Invoke-Command -ComputerName db4 -ScriptBlock{ ls c:\ }
Invoke-Command -ComputerName db5 -ScriptBlock{ ls c:\ }
二、遠程拷貝文件
將本機c:\a文件拷貝到目標主機查下c:\b,參數-Recurse是遞歸拷貝,針對目錄拷貝使用,單個文件不需要。
$Session = new-PSSession -ComputerName hostname
Copy-Item -Path c:\a -Destination C:\b -ToSession $Session -Recurse
將目標主機上的某個文件拷貝到本地,使用的參數是 FromSession
$Session = new-PSSession -ComputerName hostname
Copy-Item -Path c:\a -Destination C:\b -FromSession $Session -Recurse
三、遠程后台執行任務
有些時候,我們需要並行執行某些任務來提高執行的效率,在本地有Start-job命令可以實現,Invoke-Command命令同樣提供了這樣的功能,那就是使用-AsJob參數,可以將需要遠程執行的命令放在遠程機的后台執行。
Invoke-Command -ComputerName "hostname" -AsJob { sleep 100 } -Credential $Cred
這條命令就可以在遠程機上后台執行一個“sleep 100”的命令。但是執行這條命令實際需要的時間要比100s長。
以上從三個方面學習了invoke-command命令,遠程執行、遠程拷貝文件、遠程后台執行任務,學會以上3個用法常規操作就不會存在什么問題了。
參考:https://www.cnblogs.com/sparkdev/p/7200004.html