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

获取OU中运行时长最长的4台设备并远程执行脚本的问题求助

问题根因
  • Format-*系列cmdlet返回的是控制台渲染用的格式对象,不是原始数据对象,无法从中提取ComputerName属性用于后续逻辑
  • OutVariable参数使用错误:该参数仅需传入变量名的字符串,不需要加$前缀和ToString()调用,原代码未正确给$Top4赋值,循环时变量为空自然报错
  • 额外潜在问题:手动用+=构建数组效率低,Get-WmiObject已被微软弃用,无错误处理逻辑会因离线设备导致脚本报错。
修正后完整代码
$scriptBlock = { 
    $osInfo = Get-CimInstance -Class Win32_OperatingSystem
    ($osInfo.LocalDateTime - $osInfo.LastBootUpTime).TotalHours
}

# 直接管道赋值,无需手动构建数组
$UpTime = Get-ADComputer -Filter 'ObjectClass -eq "Computer"' -SearchBase "OU=***,OU=***,OU=***,DC=***,DC=***" -SearchScope Subtree | ForEach-Object {
    $uptimeValue = Invoke-Command -ComputerName $_.DNSHostName -ScriptBlock $scriptBlock -ErrorAction SilentlyContinue
    # 过滤无法连接的设备
    if ($null -ne $uptimeValue) {
        [PSCustomObject]@{
            ComputerName = $_.DNSHostName
            UpTimeHours  = $uptimeValue
        }
    }
}

# 先完成筛选排序取前4,存入原始数据对象到$Top4
$Top4 = $UpTime | Sort-Object -Property UpTimeHours -Descending | Select-Object -First 4 -Property ComputerName, @{
    Name = "UpTimeHours"
    Expression = { $_.UpTimeHours.ToString("#.##") }
}

# 需要控制台展示时单独调用Format-Table
$Top4 | Format-Table -AutoSize

# 遍历执行命令,可正常读取ComputerName属性
foreach ($Server in $Top4.ComputerName) {
    Invoke-Command -ComputerName $Server -ScriptBlock { HOSTNAME.EXE }
    # 执行设备本地脚本替换为:& "C:\你的本地脚本路径\脚本名.ps1"
}
关键修改说明
  1. 拆分数据处理和展示逻辑:筛选排序阶段直接保存原始数据对象到$Top4,需要展示时单独调用Format-Table,不影响后续数据读取
  2. 替换弃用接口:将Get-WmiObject替换为官方推荐的Get-CimInstance,兼容性和稳定性更好
  3. 增加错误处理:调用Invoke-Command时添加静默错误处理,自动跳过离线/无法连接的设备,避免脚本异常终止
  4. 优化数组构建逻辑:直接用管道输出给变量赋值,替代低效率的+=手动数组合并

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:06:03