有没有办法,在'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" ; 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以便我可以重新使用其他开关块中的语句,而不是额外的'ifs'
,那将会更优雅。答案 0 :(得分:0)
虽然我认为您不能更改switch
语句变量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语句。您可以重新组织if
语句,以便它们只显示一次。不幸的是,没有办法让switch语句改变变量mid-switch。从您的评论中,您可以添加一个额外的参数来指定类型,因此您可以根据类型使用一个大的switch语句。像这样:
switch ($DataType) {
"String" {<#Things to do if string#>}
"OtherTypes" {<#Continue like this#>}
}#End Switch ($DataType)
我想在那时,我会开始使用参数集。这是一篇描述Parameter Sets
的博客答案 1 :(得分: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'
#>