文章目录
  • abstract
  • 为什么考虑命令行连接
  • 讨论主题
  • powershell远程控制
  • 使用PowerShell远程管理
  • 前提条件:
  • 步骤:
  • 1. 启用WinRM服务
  • 2. 配置信任主机
  • 3. 测试连接
  • 4. 创建远程会话
  • 5. 运行远程命令
  • 6. 关闭会话
  • 例子
  • 小结
  • SSH方案
  • 基础连接
  • 免密自动登录
  • 修改配置文件
  • 在ssh server端创建支持免密登录的公钥文件
  • 重启服务
  • 尝试免密登录
  • 配置默认shell


abstract

  • 对于两台windows设备,统一网络下经常用远程桌面来控制(mstsc)
  • 而用命令行来控制也是可以的,虽然windows主打可视化操作而非命令行,但是命令行也可以执行很多基础操作
  • 命令行下,可以执行比如文件管理,资源下载,软件安装不在话下,也可以利用vscode等代码编辑器借助Remote-SSH远程编辑代码
为什么考虑命令行连接
  • 命令行连接的一个好处在于资源消耗小,连接快捷,体验一致性好
  • 另外,现在windows命令行中也可以做到以管理员方式运行命令行
  • windows 11 24h2开始开发者模式中支持sudo运行
  • 而windows10也可以安装一些命令行工具比如scoop,然后下载诸如gsudo等工具实现类似效果
PS> scoop search sudo
Results from local buckets...

Name    Version      Source Binaries
----    -------      ------ --------
gsudo   2.4.4        main
psutils 0.2023.06.28 main   sudo.ps1
sudo    0.2020.01.26 main
nsudo   8.2          extras
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
讨论主题
  • 假设局域网内我有两台windows设备,如何在设备A用命令行控制另一台设备B?
  • 也就是说,把设备B作为server,设备A作为Client

powershell远程控制

在局域网内,你可以通过多种方法在设备A上使用命令行控制设备B。下面介绍一种常见的方法,即使用PowerShell和Windows远程管理(WinRM)。

使用PowerShell远程管理

前提条件:
  1. 启用WinRM服务:WinRM服务需要在两台设备上启用。
  2. 配置信任主机:设备A需要信任设备B。
  3. 用户权限:确保你有足够的权限来执行远程命令。
步骤:
1. 启用WinRM服务

在设备A和设备B上,都需要启用WinRM服务。打开PowerShell并运行以下命令:

Enable-PSRemoting -Force
  • 1.
2. 配置信任主机

在设备A上,配置信任主机,使其可以与设备B进行通信。假设设备B的IP地址是$ip=192.168.1.198

$ip=192.168.1.198 #根据自己的情况修改
  • 1.

配置设备B为信任设备

Set-Item WSMan:\localhost\Client\TrustedHosts -Value "$ip"
  • 1.

你可以用逗号分隔多个IP地址。如果你想信任所有主机,可以使用通配符*,但这可能会有安全风险:

Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*"
  • 1.
3. 测试连接

在设备A上,使用以下命令测试与设备B的连接:

Test-WsMan -ComputerName $ip
  • 1.

如果一切正常,你应该看到一个成功的响应。

例如

PS C:\repos\scripts> Test-WsMan -ComputerName $ip

wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 0.0.0 SP: 0.0 Stack: 3.0
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
4. 创建远程会话

在设备A上,创建一个到设备B的远程会话:

$s = New-PSSession -ComputerName $ip -Credential (Get-Credential)
  • 1.

此命令会提示你输入设备B的用户名和密码。

5. 运行远程命令

现在,你可以在设备A上运行命令来控制设备B。例如,查看设备B上的进程:

Invoke-Command -Session $s -ScriptBlock { Get-Process }
  • 1.
6. 关闭会话

完成操作后,记得关闭远程会话:

Remove-PSSession -Session $s
  • 1.
例子

假设你想在设备A上获取设备B的主机名。你可以运行以下命令:

Invoke-Command -Session $s -ScriptBlock { hostname}
  • 1.
PS C:\Users\cxxu>  Invoke-Command -Session $s -ScriptBlock { hostname}
RedmiBookPC
  • 1.
  • 2.

而查看目录可能不会得到正确的结果

PS C:\repos\scripts> invoke-command -Session $s -ScriptBlock {ls C:\share}

    Directory: C:\share

Mode                 LastWriteTime         Length Name              PSComputerName
----                 -------------         ------ ----              --------------
                                                                    192.168.1.198
                                                                    192.168.1.198
                                                                    192.168.1.198
                                                                    192.168.1.198
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

通过以上步骤,你就可以在设备A上通过命令行控制设备B了。如果在过程中遇到任何问题,请检查防火墙设置或用户权限。

小结
  • 这种方式不是很优雅,连贯性和便利性不足

SSH方案

windows上需要手动安装ssh server软件(拓展模块),并且配置防火墙和服务自启动等设置

 Get started with OpenSSH for Windows | Microsoft Learn

此外,官方文档还介绍了更多连接以及可以自定义配置的方案

 Key-based authentication in OpenSSH for Windows | Microsoft Learn

 OpenSSH Server configuration for Windows | Microsoft Learn

中文文档:

 适用于 Windows 的 OpenSSH 服务器配置 | Microsoft Learn

基础连接
  • 在server端安装必要的ssh服务软件
  • 管理员方式运行powershell执行以下内容:
# Install the OpenSSH Server
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
  • 1.
  • 2.
  • 详情另见它文(防火墙配置等)
  • Client连接Server
  • 一般的连接命令行格式ssh user@server
  • 如果两个设备都开启了网络发现,那么可以用以下格式连接:``ssh user@serverName`
  • 对于小型网络通常不用关心域,完整格式其实是ssh domain\username@servername,而经常省略掉domain\这部分内容
PS C:\Users\cxxu> ssh cxxu@redmibookpc
#如果是初次连接,会有一段安全询问,通常输入yes即可
cxxu@redmibookpc's password:
Microsoft Windows [版本 10.0.19045.4529]
(c) Microsoft Corporation。保留所有权利。

cxxu@REDMIBOOKPC C:\Users\cxxu>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 否则用ssh user@serverIp来连接
PS> ssh cxxu@192.168.1.198
#如果是初次连接,会有一段安全询问,通常输入yes即可(这里演示第一次连接的询问)
The authenticity of host '192.168.1.198 (192.168.1.198)' can't be established.
ED25519 key fingerprint is SHA256:+iQOIn71iEoPaKOzM8PXC7vyqCY3QC8yGolnxdN2ncs.
This host key is known by the following other names/addresses:
    C:\Users\cxxu/.ssh/known_hosts:13: redmibookpc
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.1.198' (ED25519) to the list of known hosts.
cxxu@192.168.1.198's password:
Microsoft Windows [版本 10.0.19045.4529]
(c) Microsoft Corporation。保留所有权利。

cxxu@REDMIBOOKPC C:\Users\cxxu>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
免密自动登录
  • 和linux server类似,但是windows 中需要修改的ssh服务器端的配置文件位置和linux不同(毕竟文件系统不同)
  • 一般在C:\ProgramData\ssh目录下面的sshd_config文件中
  • 这里给出简单的过程,完善的文档参考前面列出的参考文档链接
修改配置文件
  • 您可以尝试用type C:\ProgramData\ssh\sshd_config命令行来查看配置文件中的内容
  • 默认情况下的配置文件无法直接免密登录,您需要修改部分内容(其实默认文件中大多都是注释语句,有些需要我们解开注释,有些需要我们转为注释)
  • 参考:在Windows Server 之间配置SSH 免密登录 - LearningAlbum
  • 这里直接给出我已经修改过的一个可以免密登录ssh的配置文件(sshd_config)
# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey __PROGRAMDATA__/ssh/ssh_host_rsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_dsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ecdsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile	.ssh/authorized_keys

#AuthorizedPrincipalsFile none

# For this to work you will also need host keys in %programData%/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

# GSSAPI options
#GSSAPIAuthentication no

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#PermitUserEnvironment no
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# override default of no subsystems
Subsystem	sftp	sftp-server.exe

# Example of overriding settings on a per-user basis
#Match User anoncvs
#	AllowTcpForwarding no
#	PermitTTY no
#	ForceCommand cvs server

# Match Group administrators
#        AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.

其实总得就保留了三条配置,其余都是注释掉:(不同版本的openssh server可能有所不同)

PubkeyAuthentication yes
AuthorizedKeysFile	.ssh/authorized_keys
Subsystem	sftp	sftp-server.exe
  • 1.
  • 2.
  • 3.
在ssh server端创建支持免密登录的公钥文件
  • 默认情况下,这个文件为~/.ssh/authorized_keys
  • 方式有多种,以下方案提供的命令行直接在ssh client的命令行中执行(powershell)
  • 首先确定Client端的公钥文件位置
$pubkey="$home\.ssh\id_*pub"
  • 1.
  • 其中id_*pub可能需要您补全(比如id_ed25519.pub),特别是您创建了多个不同的ssh key时,如果创建过一个,那么通常可以不修改直接执行
  • 可以从而ssh client端上传到server
# $server='redmibookpc' #局域网内启用网络发现的话可以直接用计算机名
$server='192.168.1.198' #更通用的是使用server的ip地址
scp $pubkey $user_name@${Server}:~/.ssh/authorized_keys
  • 1.
  • 2.
  • 3.
  • 也可以复制公钥到剪切板,然后登录到server中创建相应文件
  • 查看公钥
type $pubkey #该值同上述指定
  • 1.
  • 复制输出的内容,在Server端创建文件~/.ssh/authorized_keys,并插入复制的内容
重启服务
Restart-Service sshd
  • 1.
尝试免密登录
PS> ssh cxxu@redmibookpc
Microsoft Windows [版本 10.0.19045.4529]
(c) Microsoft Corporation。保留所有权利。
  • 1.
  • 2.
  • 3.

如果顺利的话,就可以登录到远程windows server (ssh),默认命令行shell是cmd

输入powershellpwsh可以切换shell

配置默认shell
PS> $env:path -split ';'|sls ssh

C:\WINDOWS\System32\OpenSSH\
  • 1.
  • 2.
  • 3.
  • 然后需要修改注册表,并且可以通过一个一句就可以实现修改
  • 首先登录到windows ssh server,确保shell处于管理员模式
  • 然后选择以下一个语句进行执行
  • 修改为自带的powershell版本
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
  • 1.
  • 修改为powershell7
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Program Files\powershell\7\pwsh.exe" -
PropertyType String -Force
  • 1.
  • 2.
  • 示例:修改为powershell7
PS> New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Program Files\powershell\7\pwsh.exe" -
PropertyType String -Force

DefaultShell : C:\Program Files\powershell\7\pwsh.exe
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\OpenSSH
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE
PSChildName  : OpenSSH
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

从ssh Client 建立ssh连接,可以看到,默认shell为powershell7

PS> ssh cxxu@redmibookpc
PowerShell 7.4.3
PS C:\Users\cxxu>
  • 1.
  • 2.
  • 3.