远程操作
在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