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

PowerShell脚本'timeoffs'属性找不到问题求助及空值处理咨询

问题:PowerShell脚本GetoffTime函数报错"The property 'timeoffs' cannot be found on this object"

编写的PowerShell脚本中GetoffTime函数执行时抛出错误:"The property 'timeoffs' cannot be found on this object",但已确认该属性确实存在。手动执行函数内的Invoke-WebRequest请求并通过ConvertFrom-Json转换后,能正常看到'timeoffs'属性;在Shell中直接执行该函数也无报错,但设置StrictMode 2.0后可复现错误。发现部分返回的JSON中timeoffs为空数组,需要解决报错并实现跳过空值的方法。


相关函数代码

function GetoffTime($startDate, $endDate, $teamUsers) {
    foreach ($user in $teamUsers){
      $body = @{
      "users" = @($user)
      } | ConvertTo-Json -compress
      
      $response = Invoke-WebRequest -Uri $URL -Method POST -Headers $headers -ContentType "application/json" -Body $body
      if ($response.StatusCode -eq "200") {
        $data = ConvertFrom-Json $response
        
        foreach($element in $data){
            # 下面的if语句会抛出属性不存在的错误
            if($element.items.timeoffs.start.date){
            $timeoff += @{
              username = $element.items.username
              date = $element.items.timeoffs.start.date | Sort-Object
            }
    }
  }
  catch {
      Log-msg
  }
  return $timeoff
}

交互模式下空值示例

PS C:\Users> $data

items
-----
{@{username=user; email=user@search.com; timeoffs=System.Object[]}}


PS C:\Users> $data.items

username email                   timeoffs
-------- -----                   --------
user     user@search.com         {}

日志输出示例

PS C:\Users> GetTimeoffData $startDate $endDate $teamUsers
1727004858.89624 INFO Fetching timeoff data from Google Calendar
https://myapi.com/v1/timeoffs/?timeMin=2024-08-01&timeMax=2024-09-30

user1
user = 'user1'
json = '{"items":[{"username":"user1","email":"user1@search","timeoffs":[]}]}'
user2
user = 'user2'
json = '{"items":[{"username":"user2","email":"user2@search","timeoffs":[]}]}'
...(其余日志内容略)

解决方案

1. 根本原因

当timeoffs是空数组时,$element.items.timeoffs是一个空集合,此时尝试访问它的start属性,在StrictMode 2.0下会直接抛出属性不存在的错误——因为空数组没有start成员。而无StrictMode时PowerShell会静默返回$null,不会触发报错。

2. 修复步骤

(1)添加空值检查逻辑

先判断timeoffs是否非空,再访问内部属性:

foreach($element in $data){
    # 先检查timeoffs是否有内容
    if ($element.items.timeoffs -and $element.items.timeoffs.start.date) {
        $timeoff += @{
            username = $element.items.username
            date = $element.items.timeoffs.start.date | Sort-Object
        }
    }
}

(2)使用安全导航运算符(PowerShell 3.0+)

如果你的PowerShell版本支持(3.0及以上),可以用?.安全导航运算符,避免空值链报错:

foreach($element in $data){
    $startDate = $element.items.timeoffs?.start?.date
    if ($startDate) {
        $timeoff += @{
            username = $element.items.username
            date = $startDate | Sort-Object
        }
    }
}

(3)初始化$timeoff变量

原代码中$timeoff未初始化,当没有符合条件的条目时会报错,建议在函数开头添加:

$timeoff = @()

(4)修正循环与响应解析逻辑

原代码中foreach($element in $data)遍历的是顶级属性,但从返回结果看$data只有items属性,且items是数组,应该直接遍历$data.items;同时解析响应时应使用$response.Content而非直接传入$response:

if ($response.StatusCode -eq 200) { # 用数字200而非字符串
    $data = ConvertFrom-Json $response.Content
    foreach($item in $data.items){
        $startDates = $item.timeoffs?.start?.date
        if ($startDates) {
            $timeoff += @{
                username = $item.username
                date = $startDates | Sort-Object
            }
        }
    }
}

3. 完整修复后的函数

function GetoffTime($startDate, $endDate, $teamUsers) {
    $timeoff = @() # 初始化结果数组
    foreach ($user in $teamUsers){
        $body = @{
            "users" = @($user)
        } | ConvertTo-Json -compress
        
        try { # 将try放到循环内,避免单个用户请求失败中断整个函数
            $response = Invoke-WebRequest -Uri $URL -Method POST -Headers $headers -ContentType "application/json" -Body $body
            if ($response.StatusCode -eq 200) {
                $data = ConvertFrom-Json $response.Content
                foreach($item in $data.items){
                    # 使用安全导航运算符避免空值报错
                    $startDates = $item.timeoffs?.start?.date
                    if ($startDates) {
                        $timeoff += @{
                            username = $item.username
                            date = $startDates | Sort-Object
                        }
                    }
                }
            }
        }
        catch {
            Log-msg # 可补充错误信息:Log-msg "处理用户$user时出错: $_"
        }
    }
    return $timeoff
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:35:24