62、PowerShell 编程:条件、循环及 .NET 交互全解析

PowerShell条件循环与.NET交互

PowerShell 编程:条件、循环及 .NET 交互全解析

1. 条件语句

条件语句在 PowerShell 中能改变脚本的执行流程,常见的条件语句有 if elseif else 语句,以及 switch 语句。

1.1 if、elseif 和 else 语句

if elseif else 语句的基本语法如下:

if(condition)
{
   statement block
}
elseif(condition)
{
   statement block
}
else
{
   statement block
}

如果 condition 计算结果为 $true ,PowerShell 会执行对应的语句块;若为 $false ,则会依次计算后续的 elseif 条件,直到找到匹配的条件。若所有条件都不匹配,会执行 else 语句块。

示例代码:

$textToMatch = Read-Host "Enter some text"
$matchType = Read-Host "Apply Simple or Regex matching?"
$pattern = Read-Host "Match pattern"
if($matchType -eq "Simple")
{
    $textToMatch -like $pattern
}
elseif($matchType -eq "Regex")
{
    $textToMatch -match $pattern
}
else
{
    Write-Host "Match type must be Simple or Regex"
}
1.2 switch 语句

switch 语句的语法有两种形式:

switch options expression
{
   comparison value           { statement block }
   -or-
   { comparison expression }  { statement block }
   (...)
   default                    { statement block }
}

switch options -file filename
{
   comparison value           { statement block }
   -or
   { comparison expression }  { statement block }
   (...)
   default                    { statement block }
}

PowerShell 计算 switch 语句时,会将 expression switch 主体中的语句进行比较。 switch 语句支持多种选项,如下表所示:
| 选项 | 含义 |
| ---- | ---- |
| -casesensitive (-c) | 区分大小写的匹配。只有当前输入项与比较值完全匹配(大小写敏感)时,才会执行关联的语句块。 |
| -exact (-e) | 精确匹配。当前输入项与比较值完全匹配(不区分大小写)时,执行关联的语句块,这是默认模式。 |
| -regex (-r) | 正则表达式匹配。当前输入项与比较值指定的正则表达式匹配(不区分大小写)时,执行关联的语句块。 |
| -wildcard (-w) | 通配符匹配。当前输入项与比较值指定的通配符匹配(不区分大小写)时,执行关联的语句块。通配符支持 ? (任意单个未指定字符)、 * (零个或多个未指定字符)、 [a-b] (a - b 范围内的任意字符)、 [ab] (指定字符 a 或 b)。 |

示例代码:

$myPhones = "(555) 555-1212","555-1234"
switch -regex ($myPhones)
{
  { $_.Length -le 8 }  { "Area code was not specified"; break }
  { $_.Length -gt 8 }  { "Area code was specified" }
  "\((555)\).*"        { "In the $($matches[1]) area code" }
}

输出结果:

Area code was specified
In the 555 area code
Area code was not specified
2. 循环语句

循环语句能让 PowerShell 多次执行一组语句,常见的循环语句有 for foreach while do … while do … until 语句。

2.1 for 语句

for 语句的基本语法如下:

:loop_label for (initialization; condition; increment)
{
   statement block
}

PowerShell 执行 for 语句时,先执行 initialization 表达式,然后计算 condition 。若 condition $true ,则执行语句块,接着执行 increment 表达式,只要 condition $true ,就会继续执行语句块和 increment 语句。

示例代码:

for($counter = 0; $counter -lt 10; $counter++)
{
    Write-Host "Processing item $counter"
}
2.2 foreach 语句

foreach 语句的基本语法如下:

:loop_label foreach (variable in expression)
{
   statement block
}

PowerShell 执行 foreach 语句时,会执行 expression 给出的管道,为表达式产生的每个项,将其赋值给 variable ,然后执行语句块。

示例代码:

$handleSum = 0;
foreach($process in Get-Process |
    Where-Object { $_.Handles -gt 500 })
{
   $handleSum += $process.Handles
}
$handleSum
2.3 while 语句

while 语句的基本语法如下:

:loop_label while(condition)
{
   statement block
}

PowerShell 执行 while 语句时,先计算 condition 表达式。若为 $true ,则执行语句块,只要 condition $true ,就会继续执行语句块。

示例代码:

$command = "";
while($command -notmatch "quit")
{
   $command = Read-Host "Enter your command"
}
2.4 do … while 和 do … until 语句

do … while do … until 语句的基本语法如下:

:loop_label do
{
   statement block
} while(condition)

:loop_label do
{
   statement block
} until(condition)

PowerShell 执行 do … while do … until 语句时,先执行语句块。在 do … while 语句中,只要 condition $true ,就会继续执行语句块;在 do … until 语句中,只要 condition $false ,就会继续执行语句。

示例代码:

$validResponses = "Yes","No"
$response = ""
do
{
   $response = read-host "Yes or No?"
} while($validResponses -notcontains $response)
"Got it."
$response = ""
do
{
   $response = read-host "Yes or No?"
} until($validResponses -contains $response)
"Got it."
3. 流程控制语句

PowerShell 支持 break continue 语句来控制循环内的流程。

3.1 break 语句

break 语句会停止当前循环的执行,PowerShell 会从当前循环语句的末尾继续执行。

示例代码:

for($counter = 0; $counter -lt 5; $counter++)
{
    for($counter2 = 0; $counter2 -lt 5; $counter2++)
    {
        if($counter2 -eq 2)
        {
            break
        }
        Write-Host "Processing item $counter,$counter2"
    }
}

输出结果:

Processing item 0,0
Processing item 0,1
Processing item 1,0
Processing item 1,1
Processing item 2,0
Processing item 2,1
Processing item 3,0
Processing item 3,1
Processing item 4,0
Processing item 4,1

若指定标签,如 break outer_loop ,则会停止该标签对应的循环。

示例代码:

:outer_loop for($counter = 0; $counter -lt 5; $counter++)
{
    for($counter2 = 0; $counter2 -lt 5; $counter2++)
    {
        if($counter2 -eq 2)
        {
            break outer_loop
        }
        Write-Host "Processing item $counter,$counter2"
    }
}

输出结果:

Processing item 0,0
Processing item 0,1
3.2 continue 语句

continue 语句会跳过当前语句块的剩余部分,然后继续当前循环的下一次迭代。

示例代码:

for($counter = 0; $counter -lt 5; $counter++)
{
    for($counter2 = 0; $counter2 -lt 5; $counter2++)
    {
        if($counter2 -eq 2)
        {
            continue
        }
        Write-Host "Processing item $counter,$counter2"
    }
}

输出结果:

Processing item 0,0
Processing item 0,1
Processing item 0,3
Processing item 0,4
Processing item 1,0
Processing item 1,1
Processing item 1,3
Processing item 1,4
Processing item 2,0
Processing item 2,1
Processing item 2,3
Processing item 2,4
Processing item 3,0
Processing item 3,1
Processing item 3,3
Processing item 3,4
Processing item 4,0
Processing item 4,1
Processing item 4,3
Processing item 4,4

若指定标签,如 continue outer_loop ,则会继续该标签对应循环的下一次迭代。

示例代码:

:outer_loop for($counter = 0; $counter -lt 5; $counter++)
{
    for($counter2 = 0; $counter2 -lt 5; $counter2++)
    {
        if($counter2 -eq 2)
        {
            continue outer_loop
        }
        Write-Host "Processing item $counter,$counter2"
    }
}

输出结果:

Processing item 0,0
Processing item 0,1
Processing item 1,0
Processing item 1,1
Processing item 2,0
Processing item 2,1
Processing item 3,0
Processing item 3,1
Processing item 4,0
Processing item 4,1
4. 工作流特定语句

在工作流中,PowerShell 支持 InlineScript Parallel Sequence foreach -parallel 语句。

4.1 InlineScript

InlineScript 关键字定义一个 PowerShell 脚本岛,会作为一个单元调用,具有传统 PowerShell 脚本语义。

示例代码:

workflow MyWorkflow
{
    ## Method invocation not supported in a workflow
    ## [Math]::Sqrt(100)

    InlineScript
    {
        ## Supported in an InlineScript
        [Math]::Sqrt(100)
    }
}
4.2 Parallel/Sequence

Parallel 关键字指定语句块内的所有语句应并行运行, Sequence 关键字用于将应作为一个单元运行的语句分组。

示例代码:

workflow MyWorkflow
{
    Parallel
    {
        InlineScript { Start-Sleep -Seconds 2; "One thing run in parallel" }
        InlineScript { Start-Sleep -Seconds 4; "Another thing run in parallel" }
        InlineScript { Start-Sleep -Seconds 3; "A third thing run in parallel" }
        Sequence
        {
            Start-Sleep -Seconds 1
            "A fourth"
            "and fifth thing run as a unit, in parallel"
        }
    }
}
4.3 Foreach -Parallel

Foreach -Parallel 类似于传统的 foreach 语句,但会并行处理集合的每个元素。

示例代码:

workflow MyWorkflow
{
    $items = 1..10
    foreach -parallel ($item in $items)
    {
        $sleep = Get-Random -Max 200
        Start-Sleep -Milliseconds $sleep
        $item
    }
}
5. 与 .NET 框架交互

PowerShell 能借助 Microsoft 的 .NET 框架进行系统管理和应用开发,主要通过调用方法或访问属性来与 .NET 框架交互。

5.1 静态方法

调用类的静态方法,语法如下:

[ClassName]::MethodName(parameter list)

示例代码:

PS > [System.Diagnostics.Process]::GetProcessById(0)

输出结果:

Handles  NPM(K)    PM(K)      WS(K) VM(M)  CPU(s)     Id ProcessName
-------  ------    -----      ----- -----  ------     -- -----------
      0       0        0         16     0              0 Idle
5.2 实例方法

调用对象实例的方法,语法如下:

$objectReference.MethodName(parameter list)

示例代码:

PS > $process = [System.Diagnostics.Process]::GetProcessById(0)
PS > $process.Refresh()
5.3 显式实现的接口方法

调用显式实现的接口方法,语法如下:

([Interface] $objectReference).MethodName(parameter list)

示例代码:

PS > ([IConvertible] 123).ToUint16($null)
5.4 静态属性

访问类的静态属性,语法如下:

[ClassName]::PropertyName

[ClassName]::PropertyName = value

示例代码:

PS > [System.DateTime]::Now

输出结果:

Sunday, July 16, 2006 2:07:20 PM
5.5 实例属性

访问对象的实例属性,语法如下:

$objectReference.PropertyName

$objectReference.PropertyName = value

示例代码:

PS > $today = [System.DateTime]::Now
PS > $today.DayOfWeek

输出结果:

Sunday
6. 了解类型

了解类和类型的主要途径有 Get-Member cmdlet 和 .NET 框架文档。

6.1 Get-Member cmdlet

使用 Get-Member cmdlet 了解给定类型支持的方法和属性,不同操作的结果如下表所示:
| 操作 | 结果 |
| ---- | ---- |
| [typename] | Get-Member -Static | 给定类型的所有静态方法和属性。 |
| $objectReference | Get-Member -Static | $objectReference 类型提供的所有静态方法和属性。 |
| $objectReference | Get-Member | $objectReference 类型提供的所有实例方法和属性。若 $objectReference 表示一个项的集合,PowerShell 会返回该集合包含的类型的实例和属性。要查看集合本身的实例和属性,使用 Get-Member 的 -InputObject 参数:Get-Member -InputObject $objectReference |
| [typename] | Get-Member | 表示此类型的 System.Runtime Type 对象的所有实例方法和属性。 |

6.2 .NET 框架文档

通过搜索功能可获取 .NET 框架类的文档,为快速找到成员文档,可在 MSDN 搜索词中添加 “members” 一词,如 “classname members”。类成员文档会列出构造函数、方法、属性等,用 S 图标表示静态方法和属性,点击成员名称可获取更多信息。

7. 类型快捷方式

指定类型名称时,PowerShell 允许对一些常见类型使用缩写形式,如下表所示:
| 类型快捷方式 | 完整类名 |
| ---- | ---- |
| [Adsi] | [System.DirectoryServices.DirectoryEntry] |
| [AdsiSearcher] | [System.DirectoryServices.DirectorySearcher] |
| [Float] | [System.Single] |
| [Hashtable] | [System.Collections.Hashtable] |
| [Int] | [System.Int32] |
| [IPAddress] | [System.Net.IPAddress] |
| [Long] | [System.Collections.Int64] |
| [PowerShell] | [System.Management.Automation.PowerShell] |
| [PSCustomObject] | [System.Management.Automation.PSObject] |
| [PSModuleInfo] | [System.Management.Automation.PSModuleInfo] |
| [PSObject] | [System.Management.Automation.PSObject] |
| [Ref] | [System.Management.Automation.PSReference] |
| [Regex] | [System.Text.RegularExpressions.Regex] |
| [Runspace] | [System.Management.Automation.Runspaces.Runspace] |
| [RunspaceFactory] | [System.Management.Automation.Runspaces.RunspaceFactory] |
| [ScriptBlock] | [System.Management.Automation.ScriptBlock] |
| [Switch] | [System.Management.Automation.SwitchParameter] |
| [Wmi] | [System.Management.ManagementObject] |
| [WmiClass] | [System.Management.ManagementClass] |
| [WmiSearcher] | [System.Management.ManagementObjectSearcher] |
| [Xml] | [System.Xml.XmlDocument] |
| [TypeName] | [System.TypeName] |

8. 创建类型实例

使用 New-Object cmdlet 创建指定类型的实例,语法如下:

$objectReference = New-Object TypeName parameters

示例代码:

$webClient = New-Object Net.WebClient
$webClient.DownloadString("http://search.msn.com")

若类型为泛型类型,需将类型参数括在方括号中:

PS > $hashtable = New-Object "System.Collections.Generic.Dictionary[String,Bool]"
PS > $hashtable["Test"] = $true

许多类型需加载定义它们的库(程序集)后才能使用,使用 Add-Type cmdlet 的 -AssemblyName 参数加载程序集。

示例代码:

PS > Add-Type -AssemblyName System.Web
PS > [Web.HttpUtility]::UrlEncode("http://www.bing.com")

输出结果:

http%3a%2f%2fwww.bing.com
9. 与 COM 对象交互

PowerShell 可像与 .NET 框架对象交互一样访问 COM 对象的方法和属性,使用 New-Object -ComObject 参数(常缩写为 -Com )结合 COM 对象的 ProgId 来交互。

示例代码:

PS > $shell = New-Object -Com Shell.Application
PS > $shell.Windows() | Select-Object LocationName,LocationUrl
10. 扩展类型

PowerShell 支持两种向任何类型添加自定义方法和属性的方式: Add-Member cmdlet 和自定义类型扩展文件。

10.1 Add-Member cmdlet

Add-Member cmdlet 可动态向对象添加方法、属性等,支持的扩展类型如下表所示:
| 成员类型 | 含义 |
| ---- | ---- |
| AliasProperty | 定义为另一个属性别名的属性。 |
| CodeProperty | 由 System.Reflection.MethodInfo 定义的属性,此方法必须是公共、静态的,返回结果(非 void),并接受一个 PsObject 类型的参数。 |
| NoteProperty | 由提供的初始值定义的属性。 |
| ScriptProperty | 由提供的脚本块定义的属性,脚本块中 $this 指当前实例。 |
| PropertySet | 定义为一组属性快捷方式的属性,用于 Select-Object 等 cmdlet。 |
| CodeMethod | 由 System.Reflection.MethodInfo 定义的方法,此方法必须是公共、静态的,并接受一个 PsObject 类型的参数。 |
| ScriptMethod | 由提供的脚本块定义的方法,脚本块中 $this 指当前实例,$args 指输入参数。 |

示例代码:

# AliasProperty
PS > $testObject = [PsObject] "Test"
PS > $testObject | Add-Member "AliasProperty" Count Length
PS > $testObject.Count
4

# NoteProperty
PS > $testObject = [PsObject] "Test"
PS > $testObject | Add-Member NoteProperty Reversed tseT
PS > $testObject.Reversed
tseT

# ScriptProperty
PS > $testObject = [PsObject] ("Hi" * 100)
PS > $testObject | Add-Member ScriptProperty IsLong {
      $this.Length -gt 100
   }
PS > $testObject.IsLong
True

# PropertySet
PS > $testObject = [PsObject] [DateTime]::Now
PS > $collection = New-Object `
       Collections.ObjectModel.Collection``1[System.String]
$collection.Add("Month")
$collection.Add("Year")
$testObject | Add-Member PropertySet MonthYear $collection
$testObject | select MonthYear
Month                                   Year
-----                                   ----
    3                                   2010

# ScriptMethod
PS > $testObject = [PsObject] "Hello"
PS > $testObject | Add-Member ScriptMethod IsLong {
      $this.Length -gt $args[0]
   }
PS > $testObject.IsLong(3)
True
PS > $testObject.IsLong(100)
False
10.2 自定义类型扩展文件

除了 Add-Member cmdlet,PowerShell 还支持配置文件,可用于自定义给定类型的所有对象,例如为所有字符串添加 Reverse() 方法或为所有类型添加 HelpUrl 属性。

PowerShell 编程:条件、循环及 .NET 交互全解析

11. 总结与应用建议

通过前面的介绍,我们已经全面了解了 PowerShell 在条件语句、循环语句、流程控制、工作流特定语句以及与 .NET 框架和 COM 对象交互等方面的知识。下面是一些在实际应用中的建议和总结。

11.1 条件与循环语句的应用
  • 条件语句 :在需要根据不同情况执行不同操作时, if-elseif-else switch 语句非常有用。例如,在脚本中根据用户输入的不同选项执行不同的任务。当条件较为简单且相互独立时,使用 if-elseif-else 语句;当需要对一个值进行多种匹配时, switch 语句更为合适。
  • 循环语句 :根据不同的需求选择合适的循环语句。 for 语句适用于已知循环次数的情况; foreach 语句适用于遍历集合中的每个元素; while do-while do-until 语句适用于根据条件进行循环的情况,其中 do-while do-until 至少会执行一次循环体。

下面是一个综合使用条件和循环语句的示例,用于统计一个数组中正数、负数和零的个数:

$numbers = -2, 0, 5, -1, 3, 0, -4
$positiveCount = 0
$negativeCount = 0
$zeroCount = 0

foreach ($number in $numbers) {
    if ($number -gt 0) {
        $positiveCount++
    } elseif ($number -lt 0) {
        $negativeCount++
    } else {
        $zeroCount++
    }
}

Write-Host "Positive numbers: $positiveCount"
Write-Host "Negative numbers: $negativeCount"
Write-Host "Zero numbers: $zeroCount"
11.2 流程控制语句的应用

break continue 语句可以帮助我们更灵活地控制循环的执行。 break 语句用于提前终止循环,而 continue 语句用于跳过当前循环的剩余部分,继续下一次循环。在嵌套循环中,使用标签可以指定要控制的具体循环。

例如,在一个二维数组中查找第一个大于 10 的元素,并输出其位置:

$matrix = @(
    @(1, 2, 3),
    @(4, 11, 6),
    @(7, 8, 9)
)

:outerLoop for ($i = 0; $i -lt $matrix.Length; $i++) {
    for ($j = 0; $j -lt $matrix[$i].Length; $j++) {
        if ($matrix[$i][$j] -gt 10) {
            Write-Host "First element greater than 10 found at position ($i, $j)"
            break outerLoop
        }
    }
}
11.3 工作流特定语句的应用

在处理复杂的任务时,工作流特定语句如 InlineScript Parallel Sequence foreach -parallel 可以提高脚本的执行效率。 InlineScript 用于在工作流中执行传统的 PowerShell 脚本; Parallel 用于并行执行多个任务; Sequence 用于将一组任务作为一个单元执行; foreach -parallel 用于并行处理集合中的元素。

例如,模拟一个并行处理多个文件的工作流:

workflow ProcessFiles {
    $files = "file1.txt", "file2.txt", "file3.txt"
    foreach -parallel ($file in $files) {
        InlineScript {
            Write-Host "Processing file: $using:file"
            Start-Sleep -Seconds 2
            Write-Host "Finished processing file: $using:file"
        }
    }
}

ProcessFiles
11.4 与 .NET 框架和 COM 对象交互的应用

PowerShell 与 .NET 框架和 COM 对象的交互能力使得我们可以利用丰富的类库和功能。在需要进行系统管理、文件操作、网络编程等方面,与 .NET 框架交互可以提供强大的支持;而与 COM 对象交互则可以访问一些旧的应用程序和系统组件。

例如,使用 .NET 框架的 System.IO 类来创建一个文件并写入内容:

$filePath = "test.txt"
$fileContent = "This is a test file."

[System.IO.File]::WriteAllText($filePath, $fileContent)
Write-Host "File created and content written."
12. 流程图示例

下面是一个简单的 mermaid 流程图,展示了 if-elseif-else 语句的执行流程:

graph TD;
    A[开始] --> B{条件1是否为真};
    B -- 是 --> C[执行语句块1];
    C --> D[结束];
    B -- 否 --> E{条件2是否为真};
    E -- 是 --> F[执行语句块2];
    F --> D;
    E -- 否 --> G[执行 else 语句块];
    G --> D;
13. 总结

PowerShell 是一个功能强大的脚本语言,通过条件语句、循环语句、流程控制语句、工作流特定语句以及与 .NET 框架和 COM 对象的交互,我们可以实现各种复杂的任务。在实际应用中,根据具体需求选择合适的语句和方法,合理利用 PowerShell 的特性,可以提高脚本的效率和可维护性。

希望本文能够帮助你更好地掌握 PowerShell 的相关知识,并在实际工作中发挥作用。不断实践和探索,你将发现 PowerShell 在系统管理和自动化任务方面的巨大潜力。

以上就是关于 PowerShell 编程的全面介绍,如果你有任何问题或建议,欢迎留言讨论。

【2025年10月最新优化算法】混沌增强领导者黏菌算法(Matlab代码实现)内容概要:本文档介绍了2025年10月最新提出的混沌增强领导者黏菌算法(Matlab代码实现),属于智能优化算法领域的一项前沿研究。该算法结合混沌机制与黏菌优化算法,通过引入领导者策略提升搜索效率和局寻优能力,适用于复杂工程优化问题的求解。文档不仅提供完整的Matlab实现代码,还涵盖了算法原理、性能验证及与其他优化算法的对比分析,体现了较强的科研复现性和应用拓展性。此外,文中列举了大量相关科研方向和技术应用场景,展示其在微电网调度、路径规划、图像处理、信号分析、电力系统优化等多个领域的广泛应用潜力。; 适合人群:具备一定编程基础和优化理论知识,从事科研工作的研究生、博士生及高校教师,尤其是关注智能优化算法及其在工程领域应用的研发人员;熟悉Matlab编程环境者更佳。; 使用场景及目标:①用于解决复杂的连续空间优化问题,如函数优化、参数辨识、工程设计等;②作为新型元启发式算法的学习与教学案例;③支持高水平论文复现与算法改进创新,推动在微电网、无人机路径规划、电力系统等实际系统中的集成应用; 其他说明:资源包含完整Matlab代码和复现指导,建议结合具体应用场景进行调试与拓展,鼓励在此基础上开展算法融合与性能优化研究。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值