windows@windows设备之间远程命令行控制方案@windows设备间使用OpenSSH

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
      

讨论主题

  • 假设局域网内我有两台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
2. 配置信任主机

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

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

配置设备B为信任设备

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

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

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

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

Test-WsMan -ComputerName $ip

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

例如

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
4. 创建远程会话

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

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

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

5. 运行远程命令

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

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

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

Remove-PSSession -Session $s

例子

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

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

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

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

通过以上步骤,你就可以在设备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
      
    • 详情另见它文(防火墙配置等)

  • 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>
        
    • 否则用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>
        
        

免密自动登录

  • 和linux server类似,但是windows 中需要修改的ssh服务器端的配置文件位置和linux不同(毕竟文件系统不同)
  • 一般在C:\ProgramData\ssh目录下面的sshd_config文件中
  • 这里给出简单的过程,完善的文档参考前面列出的参考文档链接
修改配置文件
  • 您可以尝试用type C:\ProgramData\ssh\sshd_config命令行来查看配置文件中的内容

  • 默认情况下的配置文件无法直接免密登录,您需要修改部分内容(其实默认文件中大多都是注释语句,有些需要我们解开注释,有些需要我们转为注释)

  • 这里直接给出我已经修改过的一个可以免密登录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
    
    

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

    PubkeyAuthentication yes
    AuthorizedKeysFile	.ssh/authorized_keys
    Subsystem	sftp	sftp-server.exe
    
在ssh server端创建支持免密登录的公钥文件
  • 默认情况下,这个文件为~/.ssh/authorized_keys

  • 方式有多种,以下方案提供的命令行直接在ssh client的命令行中执行(powershell)

  • 首先确定Client端的公钥文件位置

    • $pubkey="$home\.ssh\id_*pub"
      
    • 其中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 
      
  • 也可以复制公钥到剪切板,然后登录到server中创建相应文件

    • 查看公钥

      type $pubkey #该值同上述指定
      
    • 复制输出的内容,在Server端创建文件~/.ssh/authorized_keys,并插入复制的内容

重启服务
Restart-Service sshd
尝试免密登录
PS> ssh cxxu@redmibookpc
Microsoft Windows [版本 10.0.19045.4529]
(c) Microsoft Corporation。保留所有权利。

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

输入powershellpwsh可以切换shell

配置默认shell

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

  • windows ssh server默认的shell是cmd,这是一个过时的shell

  • 我们可以更改为powershell或其他shell

  • 首先查看openssh是否安装在默认路径:

    PS> $env:path -split ';'|sls ssh
    
    C:\WINDOWS\System32\OpenSSH\
    
    
  • 然后需要修改注册表,并且可以通过一个一句就可以实现修改

  • 首先登录到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
      
    • 修改为powershell7

      New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Program Files\powershell\7\pwsh.exe" -
      PropertyType String -Force
      
      
  • 示例:修改为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
    
    

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

    PS> ssh cxxu@redmibookpc
    PowerShell 7.4.3
    PS C:\Users\cxxu> 
    

相关推荐

  1. 无人机如何远程控制其他设备

    2024-07-10 03:00:05       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 03:00:05       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 03:00:05       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 03:00:05       57 阅读
  4. Python语言-面向对象

    2024-07-10 03:00:05       68 阅读

热门阅读

  1. 揭秘CSS:link与@import的实战应用

    2024-07-10 03:00:05       20 阅读
  2. LeetCode 算法:课程表 c++

    2024-07-10 03:00:05       22 阅读
  3. UniVue@v1.2.0版本发布

    2024-07-10 03:00:05       25 阅读
  4. 【Lua】元表使用示例

    2024-07-10 03:00:05       25 阅读
  5. 使用 apktool 解包 apk 并重新打包签名

    2024-07-10 03:00:05       21 阅读
  6. Mobile ALOHA前传之VINN, Diffusion Policy和ACT对比

    2024-07-10 03:00:05       24 阅读
  7. React面试题之setState的执行机制

    2024-07-10 03:00:05       23 阅读
  8. 如何控制代码质量

    2024-07-10 03:00:05       22 阅读