1

我有一个类似于以下的文件

C:\path\AP1\com1\web.config
C:\path\AP2\com1\web.config
C:\path\AP1\com2\web.config
C:\path\AP2\com2\web.config
C:\path\AP1\com4new\web.config
C:\path\AP2\com4new\web.config
C:\path\AP1\thirdFolder\web.config
C:\path\AP2\thirdFolder\web.config

无论环境如何,此文件都会在每台服务器上输出。我正在创建一个验证脚本,只包含每个服务器的相关行。

服务器数据的示例如下

<server compName="serverName102">
    <ip>192.168.1.1</ip>
    <type>App</type>
    <env>test</env>
    <instances>Com2, Com3</instances>
    <AppPools>bo, fo</AppPools>
</server>

如果服务器的AppPools设置包含fo,那么我需要包含任何包含AP1. 如果AppPoolscontains bo,那么我需要AP2,显然如果它包含两者,我需要两行。

如果服务器的instancescontains Com2,那么我需要包含任何包含com2OR的行com4newCom3将是thirdFolder线条。

我目前有几个 if 语句,如下所示

if ($serverInst -like "*com2*"){
    $refinedResults += $allResults | where-object {$_ -like "*com2*" -or $_ -like "*com4new*"}
}

问题是我几乎很肯定我如何做到这一点几乎不是最好的方式,或者我应该如何做到这一点。任何人都可以提供一些关于执行此验证的最佳方法的见解吗?

4

1 回答 1

2

我看到你的方法的主要问题是你最终可能会在你的$refinedResults收藏中出现重复。

要解决此问题,您可以使用HashSetof 字符串。
如果您尝试向 HashSet 添加一个值并且它已经存在,则该操作只会返回 false 并且 Set 不会发生任何事情。

假设这$allResults是一个字符串数组,你可以这样做:

$refinedResults = New-Object System.Collections.Generic.HashSet[String]

if ($serverInst -like "*com2*")
{
    $refinedResults.UnionWith([String[]]($allResults |? {$_ -like "*com2*" -or $_ -like "*com4new*"}))
}

为了可读性(以及如果您计划一次处理多个条目的性能),您可能希望$allResults在开始匹配之前定义您的规则并从以下内容中提取:

[String[]]$resultsCom2 = $allResults |? {$_ -like "*com2*" -or $_ -like "*com4new*"}
[String[]]$resultsCom3 = $allResults |? {$_ -like "*thirdfolder*"}

$refinedResults = New-Object System.Collections.Generic.HashSet[String]

if ($serverInst -like "*com2*")
{
    $refinedResults.UnionWith($resultsCom2)
}

if ($serverInst -like "*com3*")
{
    $refinedResults.UnionWith($resultsCom3)
}

如果 $refinedResults 的实例化失败,添加:

Add-Type -AssemblyName System.Core

到你之前的脚本

于 2013-08-27T16:00:49.933 回答