【问题标题】:How to Exit a For Each Loop within a Function?如何在函数中退出 For Each 循环?
【发布时间】:2013-12-17 01:11:21
【问题描述】:

我有以下函数,旨在根据传递的命名空间递归读取机器上的所有 WMI 命名空间(默认情况下,脚本调用 ReadWMI("root")。如果 WMI 命名空间包含名称sms 或 ccm,我想测试写入该命名空间以验证写入是否有效。如果在该函数中写入 WMI 失败,我想退出 For 循环并完全退出该函数。

我注意到的是,当我退出 for 或退出函数(使用 Exit For 或 Exit Function)时,我会返回 Next 而不是完全退出函数。这会导致许多其他命名空间可以成功写入的问题。

Function ReadWMI(strNameSpace)

Dim oWMI, colNameSpaces, objNameSpace, sFullNamespace

'ReadWMI = "True"

WMI_ReadRepository = "Healthy"

On Error Resume Next

'Verify all namespaces

Set oWMI = GetObject("winmgmts:\\" & sComputer & "\" & strNameSpace)

If Err.Number <> 0 Then

    ReadWMI = "False"

    WMI_ReadRepository = "Unhealthy"

    oLog.WriteLine Now()& " - " &  "ReadWMI(): Failed to bind to WMI namespace " & strNamespace & ". Stopping WMI Verification"
    oLog.WriteLine Now()& " - " &  "ReadWMI(): Error Code: " & Err.Number
    'oLog.WriteLine Now()& " - " &  "ReadWMI(): Error Description: " & Err.Description
    Err.Clear

    Exit Function

Else

    oLog.WriteLine Now()& " - " &  "ReadWMI(): Successfully connected to WMI namespace " & strNamespace 

End If  

Set colNameSpaces = oWMI.InstancesOf("__NAMESPACE")

For Each objNameSpace In colNameSpaces

    sFullNamespace = LCase(strNamespace & "\" & objNamespace.Name)



    If InStr(sFullNamespace,"ccm") Or InStr(sFullNamespace,"sms") > 0 Then

        oLog.WriteLine Now()& " - " &  "ReadWMI(): Writing to " & sFullNamespace & " WMI Namespace if WMIWriteRepository set to TRUE"

        If WMIWriteRepository = True Then

            If WriteWMI(sFullNamespace) = "False" Then

                oLog.WriteLine Now()& " - " &  "ReadWMI(): Failed to write to namespace " & sFullNamespace

                WMI_ReadRepository = "Unhealthy"

                'ReadWMI = "False"

                Exit Function

            End If

        Else

            oLog.WriteLine Now()& " - " &  "ReadWMI(): WMIWriteRepository set to False or OS is a Server. Will not write to repository."    

        End If


    End If


    'Call VerifyWMI again to run through the next namespace     

    Call ReadWMI(sFullNamespace)

Next



'ReadWMI = "True"

'WMI_ReadRepository = "Healthy"

Set oWMI = Nothing

On Error Goto 0

End Function

【问题讨论】:

  • 您可能正在退出到较早的递归调用。
  • 你是对的,现在我查看它 vbsedit 显示 2 个递归调用,一个用于 root\ccm,一个用于 root\ccm\locationservices。不太清楚如何处理。

标签: vbscript foreach error-handling wmi onerror


【解决方案1】:

如果出现问题并且您想跳出递归函数调用,则将返回值设为False(取消注释您脚本中的'ReadWMI = "False")。

您在下一条之前的最后一条语句必须测试 WMI 的读取是否正确,所以不是

Call ReadWMI(sFullNamespace)

使用

If ReadWMI(sFullNamespace) = "False" Then
    Exit For
End If

Protip:停止使用“字符串布尔值”,它们很慢,并且错误会在拐角处引诱你在后面咬你("True" &lt;&gt; "true" &lt;&gt; "Treu" &lt;&gt; "True ")。只需使用TrueFalse。每当您想将布尔值输出到字符串时,它都会自动转换为正确的字符串值:

MsgBox True & " / " & False 
' Output: "True / False"

【讨论】:

  • 好点,感谢 Protip(我从其他人那里继承了脚本,所以我正在经历并进行这些更改)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2019-10-21
相关资源
最近更新 更多