You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于PowerShell Invoke-WebRequest实现远程设备备份的操作选项选择?

远程设备备份场景的操作选项选择逻辑实现方案

问题需求

如何在远程设备备份场景中实现操作选项的选择逻辑?能否通过函数实现,在选择对应选项时仅替换必要参数来完成操作?

背景说明

存在需按需备份的远程设备,原手动操作需登录后等待GUI完全加载(耗时5-10分钟)。已编写可用的CURL授权请求,后因命令行功能限制改写为PowerShell脚本,核心操作包含:

  • 授权登录获取session_id
  • 发送XML请求切换到备份状态
  • 发送XML请求恢复初始状态

现已添加菜单函数askchoice,需将上述PowerShell请求功能集成到菜单选项中,实现选择对应选项时执行相应操作,通过函数仅替换必要参数完成逻辑。

核心实现思路

  1. 封装公共函数:将登录获取session、发送设置请求的逻辑封装成独立函数,避免重复代码
  2. 参数化差异部分:切换备份/恢复状态的XML请求仅存在参数差异,通过函数接收参数动态生成请求体
  3. 菜单与逻辑关联:在菜单选择的switch分支中调用对应函数,传递必要参数完成操作

完整PowerShell实现代码

# 全局变量存储IP和SessionID
$Global:ip = $null
$Global:sessionId = $null

# 登录获取SessionID的函数
function Get-DeviceSession {
    param(
        [Parameter(Mandatory=$true)]
        [string]$DeviceIp
    )

    $xmlAuth = '<request method="login" request_id="1" username="name" password="pass"/>'
    
    try {
        $accessResponse = Invoke-WebRequest -Uri "http://$DeviceIp`:4000/xap2" `
            -Method Post `
            -ContentType "text/xml" `
            -Body $xmlAuth `
            -ErrorAction Stop
        
        $responseXml = [xml]$accessResponse.Content
        $Global:sessionId = $responseXml.response.session_id
        Write-Host "登录成功,SessionID: $sessionId" -ForegroundColor Green
    }
    catch {
        Write-Host "登录失败:$($_.Exception.Message)" -ForegroundColor Red
        $Global:sessionId = $null
    }
}

# 发送设备设置请求的函数
function Send-DeviceSetting {
    param(
        [Parameter(Mandatory=$true)]
        [string]$RequestId,
        [Parameter(Mandatory=$true)]
        [string]$AsiInput0Enable,
        [Parameter(Mandatory=$true)]
        [string]$AsiInput2Enable,
        [Parameter(Mandatory=$true)]
        [string]$MainGlobId
    )

    if (-not $Global:sessionId) {
        Write-Host "未获取有效Session,请先登录设备" -ForegroundColor Red
        return
    }

    # 动态生成XML请求体
    $xmlBody = @"
<request method="set" request_id="$RequestId" session_id="$Global:sessionId" return_events="false">
  <data>
    <ports>
      <asi_input enable="$AsiInput0Enable" _id="0"/>
      <asi_input enable="$AsiInput2Enable" _id="2"/>
      <_all _id="8">
        <plprep main_globid="$MainGlobId"/>
      </_all>
    </ports>
  </data>
</request>
"@

    try {
        $settingResponse = Invoke-WebRequest -Uri "http://$Global:ip`:4000/xap2" `
            -Method Post `
            -ContentType "text/xml" `
            -Body $xmlBody `
            -ErrorAction Stop
        
        $responseXml = [xml]$settingResponse.Content
        $statusText = $responseXml.response.status.status_text

        if ($statusText -eq "OK") {
            Write-Host "操作执行成功:$statusText" -ForegroundColor Green
        }
        else {
            Write-Host "操作执行失败:$statusText" -ForegroundColor Red
        }
    }
    catch {
        Write-Host "请求发送失败:$($_.Exception.Message)" -ForegroundColor Red
    }
}

# 菜单显示函数
function Show-MainMenu {
    Clear-Host
    Write-Host "░░░░░ 远程设备备份菜单 ░░░░░" -BackgroundColor DarkBlue
    Write-Host "░                          ░" -BackgroundColor DarkBlue
    Write-Host "░ 1. 输入设备IP地址        ░" -BackgroundColor DarkBlue
    Write-Host "░ 2. 切换到备份状态        ░" -BackgroundColor DarkBlue
    Write-Host "░ 3. 恢复初始状态          ░" -BackgroundColor DarkBlue
    Write-Host "░ Q. 退出程序              ░" -BackgroundColor DarkBlue
    Write-Host "░                          ░" -BackgroundColor DarkBlue
    Write-Host "░░░░░░░░░░░░░░░░░░░░░░░░░░░░" -BackgroundColor DarkBlue
    Write-Host "当前设备IP地址: $($Global:ip ?? '未设置')" -ForegroundColor Green
}

# 主循环
Do {
    Show-MainMenu
    $choice = Read-Host "请选择操作选项 [1-3] 或 Q 退出"

    switch ($choice.ToLower())
    {
        "1" {
            $banList = @("10.10.10.10", "10.10.10.11", "10.10.10.12", "10.10.10.13")
            do {
                $Global:ip = Read-Host "请输入设备IP地址"
                if ($banList -contains $ip) {
                    Write-Host "该IP地址禁止访问" -ForegroundColor Red
                }
            }
            While ($banList -contains $ip)
            # 输入IP后自动登录获取Session
            Get-DeviceSession -DeviceIp $Global:ip
            pause
        }
        "2" {
            if (-not $Global:ip) {
                Write-Host "请先输入设备IP地址" -ForegroundColor Yellow
                pause
                continue
            }
            Write-Host "正在执行切换到备份状态操作..." -ForegroundColor Cyan
            Send-DeviceSetting -RequestId "2" -AsiInput0Enable "false" -AsiInput2Enable "true" -MainGlobId "2"
            pause
        }
        "3" {
            if (-not $Global:ip) {
                Write-Host "请先输入设备IP地址" -ForegroundColor Yellow
                pause
                continue
            }
            Write-Host "正在执行恢复初始状态操作..." -ForegroundColor Cyan
            Send-DeviceSetting -RequestId "3" -AsiInput0Enable "true" -AsiInput2Enable "false" -MainGlobId "0"
            pause
        }
        "q" {
            Write-Host "退出程序" -ForegroundColor Green
            exit
        }
        default {
            Write-Host "无效选项,请重新选择" -ForegroundColor Yellow
            pause
        }
    }
} 
while ($true)

代码说明

  1. 公共函数封装:
    • Get-DeviceSession:负责发送登录请求,获取并存储session_id,处理登录异常
    • Send-DeviceSetting:接收必要参数动态生成XML请求体,发送设置请求并处理响应结果
  2. 参数化处理:切换备份/恢复状态时,仅需传递不同的enable值和main_globid参数,无需重复编写XML模板
  3. 菜单逻辑优化:
    • 输入IP后自动执行登录,避免手动操作
    • 操作前检查IP和session有效性,给出友好提示
    • 统一异常处理,提升脚本健壮性

内容的提问来源于stack exchange,提问作者Vacheslav Great

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:57:32