2

有没有办法在“开关”中修改您正在评估的变量,并让它改变匹配?

$var = "a"
switch ($var){

    "a" {Write-Host "1st match for 'a'"}
    "b" {Write-Host "1st match for 'b'"}
    "a" {Write-Host "2nd match for 'a'"; $var = "b" ; continue}
    "b" {Write-Host "2st match for 'b'"}
}

我希望能够使上述内容匹配:

'a' 的第一次匹配 'a
' 的
第二次匹配 'b'的第二次匹配

$Destination = "vmstores:\vcsa@443\Training\Local-B\David" #is a param of my function, which could be a bunch of different types of object.

$DestinationType = $Destination.GetType().Name

    switch ($DestinationType){
        "String" {
            if ((Test-Path $Destination) -eq $true){
                if ((Get-Item $Destination).GetType().Name -eq "DatastoreFolderImpl"){
                    $DestinationType = "DatastoreFolderImpl"
                    if ((Test-Path $Destination.Insert($Destination.Length,"\").Insert(($Destination.Length)+1,$SourceVMXShort)) -eq $true){
                    Write-Warning "Destination File exists..."
                    $DestinationExists = $true
                    }
                }
                elseif ((Get-Item $Destination).GetType().Name -eq "DatastoreFileImpl"){
                    $DestinationType = "DatastoreFileImpl"
                    Write-Warning "Destination File exists..."
                    $DestinationExists = $true
                }
            }
             ; continue
        }
        "DirectoryInfo" {
            if ((Test-Path $Destination.Insert($Destination.Length,"\").Insert(($Destination.Length)+1,$SourceVMXShort)) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            ; break
        }
        "FileInfo" {
            if ((Test-Path $Destination) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            ; break
        }
        "DatastoreFileImpl" {
            if ((Test-Path $Destination) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            ; break
        }
        "DatastoreFolderImpl" {
            if ((Test-Path $Destination.Insert($Destination.Length,"\").Insert(($Destination.Length)+1,$SourceVMXShort)) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            ; break
        }
        "NasDatastoreImpl" {
            New-PSDrive -Name "DestMount" -Root \ -PSProvider VimDatastore -Datastore $Destination | Out-Null
            if ((Test-Path ("DestMount:").insert(10,"\").Insert(11,$SourceVMXShort)) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            $Destination = ("DestMount:").insert(10,"\")
            ; break
        }
        "VMFSDatastoreImpl" {
            New-PSDrive -Name "DestMount" -Root \ -PSProvider VimDatastore -Datastore $Destination | Out-Null
            if ((Test-Path ("DestMount:").insert(10,"\").Insert(11,$SourceVMXShort)) -eq $true){
                Write-Warning "Destination File exists..."
                $DestinationExists = $true
            }
            $Destination = ("DestMount:").insert(10,"\")
            ; break
        }

    }

如您所见,如果我可以更新 $DestinationType 会更优雅,这样我就可以在其他 switch 块中重新使用该语句,而不是额外的“ifs”

4

2 回答 2

0

虽然我认为您不能更改switchstatements 变量 mid check,但您可以执行嵌套switch语句。此代码提供您请求的输出:

$var = "a"
switch ($var){
    "a" {Write-Host "1st match for 'a'"}
    "b" {Write-Host "1st match for 'b'"}
    "a" {Write-Host "2nd match for 'a'"
            $var = "b" 
            switch ($var) {
                "b" {Write-Host "2st match for 'b'"}
            } #End sub-switch
        } #End "A" check
} #End Primary switch

现在,我不确定您的总体目标是什么,可能有更好的方法来使用函数等来做到这一点。

更新问题和评论后编辑:

通过查看更新的代码,您可以提取设置$DestinationExists = $true. 您也许可以重新组织您的if陈述,使它们只出现一次。不幸的是,没有办法让 switch 语句更改变量 mid-switch。根据您的评论,也许您可​​以添加一个额外的参数来指定类型,因此您可以使用一个基于类型的大型 switch 语句。像这样的东西:

switch ($DataType) {
    "String" {<#Things to do if string#>}
    "OtherTypes" {<#Continue like this#>}
}#End Switch ($DataType)

不过我认为,我会开始使用参数集。这是一个描述参数集的博客

于 2012-10-24T22:05:01.223 回答
0

这是一种有点复杂的方法。请注意,示例代码与 OP 中的代码相似但不同。

add-type @"

using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Management.Automation;

public class PSVarEnumeration : IEnumerable
{
    private ScriptBlock _getterScript;

    public PSVarEnumeration(ScriptBlock getterScript)
    {
        _getterScript = getterScript;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
       return (IEnumerator) GetEnumerator();
    }

    public PSVarEnumerator GetEnumerator()
    {
        return new PSVarEnumerator(_getterScript);
    }
}

public class PSVarEnumerator : IEnumerator
{
    private ScriptBlock _getterScript;
    bool areDone = false;

    // position isn't used for anything
    int position = -1;

    public PSVarEnumerator(ScriptBlock getterScript)
    {
        _getterScript = getterScript;
    }

    public bool MoveNext()
    {
        if (!areDone) {
          if (Current != null) {
            position++;
            return true;
          } else {
            areDone = true;
            return false;
          }
        } else {
          return false;
        }
    }

    public void Reset()
    {
        position = -1;
        areDone = false;
    }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public Object Current
    {
        get
        {
            Collection<PSObject> results = _getterScript.Invoke();
            return results[0];
        }
    }
}

"@

$mySwitcher ="a"
$mySwitcherScript = {$mySwitcher}
$var = new PSVarEnumeration ( $mySwitcherScript)

switch ($var){

    "a" {Write-Host "1st match for 'a'"}
    "b" {Write-Host "1st match for 'b'"}
    "a" {Write-Host "2nd match for 'a'"; $mySwitcher = "b" ; continue}
    "b" {Write-Host "2nd match for 'b'"; $mySwitcher = $null}
}

<#
Output I get is:

1st match for 'a'
2nd match for 'a'
1st match for 'b'
2nd match for 'b'

#>
于 2013-06-06T23:42:40.483 回答