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

PowerShell操作SharePoint Online列表:无法更新已有列表项

Hyper-V VM列表同步到SharePoint Online的正确实现

问题背景

需要完成Hyper-V虚拟机列表到SharePoint Online列表的同步,要求:

  • 不存在的VM项自动创建
  • 已存在的VM项更新状态
    当前已实现列表创建、列配置和新增项,但更新逻辑错误,导致所有列表项被覆盖为同一VM信息,临时用删除重建的方式替代,需要正确的增量同步逻辑。

修正后的完整脚本

#Config Variables
$vmhost = "<serverhostname>"
$ListName = $vmhost
$folderpath = "C:\scheduled tasks\hyperv-host-vm-collation-scheduled-task"

# 导出Hyper-V VM列表到CSV
$output = "$folderpath\$vmhost.csv"
Get-VM -ComputerName $vmhost | Select-Object Name,State | Export-Csv -Path $output -NoTypeInformation
$vms = Import-Csv $output

$SiteURL = "<SharePointOnlineURL>"
 
#Setup Credentials - 后续可替换为REST API获取的凭据
$UserName = ""
$Password = ''

$SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserName, $SecurePassword

#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Credentials $Cred

# 检查列表是否存在,不存在则创建并配置列
$List = Get-PnPList -Identity $ListName -ErrorAction SilentlyContinue
 
If($List -ne $Null)
{ 
    Write-Host -ForegroundColor Yellow "列表已存在,开始同步VM信息"
}
Else
{
    Write-Host -ForegroundColor Green "列表不存在,创建新列表"
    # 创建列表
    $List = New-PnPList -Title $ListName -Template GenericList -EnableVersioning
    # 添加State文本列
    Add-PnPField -List $ListName -Type Text -DisplayName State -InternalName State -AddToDefaultView -ErrorAction Stop
    # 将默认Title列重命名为Name
    Set-PnPField -List $ListName -Identity Title -Values @{Title="Name"} -ErrorAction Stop
}

# -------------------------- 核心同步逻辑 --------------------------
# 获取SharePoint列表中已有的VM项,存储为哈希表:Key=VM名称,Value=列表项ID
$existingVMs = @{}
Get-PnPListItem -List $ListName -Fields "Title", "Id" | ForEach-Object {
    $existingVMs[$_.FieldValues.Title] = $_.Id
}

# 遍历每个VM,执行新增或更新
foreach($vm in $vms){
    $vmName = $vm.Name.Trim()
    $vmState = $vm.State.Trim()

    if($existingVMs.ContainsKey($vmName)){
        # VM已存在,更新状态
        Write-Host -ForegroundColor Cyan "更新VM: $vmName"
        Set-PnPListItem -List $ListName -Identity $existingVMs[$vmName] -Values @{
            "Title" = $vmName
            "State" = $vmState
        }
        # 从哈希表中移除已处理的项,剩余的就是SharePoint中存在但Hyper-V已删除的VM
        $existingVMs.Remove($vmName)
    }
    else{
        # VM不存在,新增项
        Write-Host -ForegroundColor Green "新增VM: $vmName"
        Add-PnPListItem -List $ListName -Values @{
            "Title" = $vmName
            "State" = $vmState
        }
    }
}

# 可选:删除SharePoint中存在但Hyper-V已不存在的VM项
if($existingVMs.Count -gt 0){
    Write-Host -ForegroundColor Red "清理已删除的VM项:$($existingVMs.Keys -join ', ')"
    foreach($deletedVM in $existingVMs.Keys){
        Remove-PnPListItem -List $ListName -Identity $existingVMs[$deletedVM] -Force
    }
}

# 断开连接
Disconnect-PnPOnline

关键逻辑说明

  • 哈希表存储已有VM:通过Get-PnPListItem获取列表中所有VM的名称和ID,存入哈希表$existingVMs,实现通过VM名称快速查找对应列表项ID,避免嵌套循环导致的重复更新问题。
  • 增量同步逻辑:
    1. 遍历CSV中的每个VM,检查哈希表中是否存在该名称:存在则调用Set-PnPListItem更新状态;不存在则调用Add-PnPListItem新增。
    2. 处理完成的VM从哈希表中移除,剩余的键即为SharePoint中存在但Hyper-V已删除的VM,可选择清理。
  • 避免重复操作:移除原脚本的嵌套循环,每个VM仅处理一次,解决了所有列表项被覆盖为同一VM信息的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 10:12:45