首页 > 解决方案 > 从位于多个远程服务器上的文本文件中选择所需的内容并写入执行脚本的 csv 日志

问题描述

我正在编写一个脚本来从多个远程服务器读取文本文件,并从文本文件中获取所需的详细信息,将这些详细信息写入在执行脚本的 pc 上创建的 csv 日志文件。我想添加 try、catch 和 if 条件以使我的脚本按预期工作。要求如下:

  1. 从位于路径下的远程服务器读取文件,
  2. 替换不需要的字符(由代码 -replace 完成)
  3. 使用 set-content 保存文本文件(已经完成)
  4. 从文件中获取所需内容,存储在数组变量中(完成)
  5. 在执行脚本的 PC 上创建的日志文件 (.csv) 中写入内容。

问题是脚本获取详细信息,但是当尝试写入日志时,它没有写入并给出错误“无法索引到空数组”。

我的代码如下:

$servers = gc .\servers.txt
$Global:ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
$date = (get-date).ToString("yyyyMMdd_HHmm")
$ILOContent = "$ScriptDir\ILOConfigData_$date.csv"
Add-Content -Path $ILOContent -Value "ILO_Name,ILO_Domain,Network_Details,ILO-TimeZone,Directory_Users,LDAP_Directory_Authentication,Directory_Groups,SNMP-Settings,Directory_Server_Address"


Foreach($server in $servers){

        Invoke-Command -ComputerName $server -Credential $Credential -ScriptBlock {

                    New-Item -Path "C:\Program Files\Hewlett Packard Enterprise\HPONCFG" -ItemType File -Name Current_ILOConfig.xml -Force| Out-Null
                    Set-Location "C:\Program Files\Hewlett Packard Enterprise\HPONCFG"
                    $ILODataPath = Get-Location
                    $WantFile = "$ILODataPath\Current_ILOConfig.txt"
                    $FileExists = Test-Path $WantFile
                    If ($FileExists -eq $True) {Remove-Item $WantFile }
                    Sleep(2)
                    Write-Host "Gathering current ILO configuration for $ENV:COMPUTERNAME" 
                    & "C:\Program Files\Hewlett Packard Enterprise\HPONCFG\hponcfg.exe" /a /w `
                      "C:\Program Files\Hewlett Packard Enterprise\HPONCFG\Current_ILOConfig.xml" |Out-Null
                    
                    Get-Content .\Current_ILOConfig.xml|Set-Content "Current_ILOConfig.txt"
                    Sleep(3)
                    $ILORAW_DATA = Get-Content .\Current_ILOConfig.txt

                    $ILORAW_DATA|ForEach-Object{
                                         $_ -replace '<!-- ' `
                                            -replace ' -->' `
                                            -replace '<' `
                                            -replace ' />' `
                                            -replace '"' `
                                            }|Set-Content .\Current_ILOConfig.txt

                    $ILO_DATA = Get-Content .\Current_ILOConfig.txt
                    Write-Host "Getting DNS details"
                    $DNS_NAME = $ILO_DATA |Where {$_ |Select-String -Pattern " DNS_NAME VALUE"," DOMAIN_NAME VALUE"}
                    $ILONAME = $DNS_NAME -split "="
                    $ServerILO = $ILONAME[1]
                    $ILONAME[3]

                    Write-Host "Getting Network details"
                    $NT = $ILO_DATA | where {$_ |Select-String -Pattern " IP_ADDRESS VALUE"," SUBNET_MASK"," GATEWAY_IP_ADDRESS"," PRIM_DNS_SERVER VALUE", " SEC_DNS_SERVER VALUE"," TER_DNS_SERVER VALUE" } 
                    $Network = [array]$NT -join "`n"
                    $Network.Trim()

                    Write-Host "Getting ILO TimeZone"
                    $TZ= $ILO_DATA |Where {$_ | Select-String -Pattern " TIMEZONE VALUE"}
                    $TimeZone =$TZ -Split "="
                    $TimeZone[1]

                    #DIRECT
                    Write-Host "Getting Directory User details"
                    
                    $DIR_USER = $ILO_DATA |Where {$_ | Select-String -Pattern " DIR_USER_CONTEXT"}
                    $User =@()
                    
                        foreach($Usr in $DIR_USER)
                        {
                         $User += ($Usr -split "VALUE=")[1]
                          
                         }$User ; $DIR_USERS = [Array]$User -join "`n"

                    
                    Write-Host "getting Global:ScriptDir location"
                    Set-Location $Global:ScriptDir
                    Get-Location
                    $Data = $ILONAME[1]+$ILONAME[3]+$Network,$Model,$TimeZone[1],$DIR_USERS
                    $Data|Select-Object $ILONAME[1],$ILONAME[3],$Network,$TimeZone[1],$DIR_USERS |Export-Csv -Append -Path $ILOContent -notypeinformation                                                        

 }
 }

XML 示例:

<!-- HPONCFG VERSION = "5.4.0.0" -->
<!-- Device: iLO 5  Firmware Version : 2.44  Firmware Date : 30-4-2021 -->
<RIBCL VERSION="2.0">
    <LOGIN USER_LOGIN="admin" PASSWORD="password">
        <RIB_INFO mode="write">
            <MOD_NETWORK_SETTINGS>
                <ENABLE_NIC VALUE="Y" />
                <SHARED_NETWORK_PORT VALUE="N" />
                <VLAN_ENABLED VALUE="N" />
                <SPEED_AUTOSELECT VALUE="Y" />
                <DHCP_ENABLE VALUE="N" />
                <DHCP_GATEWAY VALUE="Y" />
                <DHCP_DNS_SERVER VALUE="Y" />
                <DHCP_WINS_SERVER VALUE="Y" />
                <DHCP_STATIC_ROUTE VALUE="Y" />
                <DHCP_DOMAIN_NAME VALUE="Y" />
                <DHCP_SNTP_SETTINGS VALUE="N" />
                <REG_WINS_SERVER VALUE="Y" />
                <REG_DDNS_SERVER VALUE="N" />
                <PING_GATEWAY VALUE="Y" />
                <IP_ADDRESS VALUE="100.11.13.65" />
                <SUBNET_MASK VALUE="255.255.255.255" />
                <GATEWAY_IP_ADDRESS VALUE="100.11.13.1" />
                <DNS_NAME VALUE="server-ilo" />
                <DOMAIN_NAME VALUE="Contasa.com" />
                <PRIM_DNS_SERVER VALUE="10.110.21.73" />
                <SEC_DNS_SERVER VALUE="10.110.21.74" />
                <TER_DNS_SERVER VALUE="10.110.21.75" />
                <PRIM_WINS_SERVER VALUE="0.0.0.0" />
                <SEC_WINS_SERVER VALUE="0.0.0.0" />
                <SNTP_SERVER1 VALUE="" />
                <SNTP_SERVER2 VALUE="" />
                <TIMEZONE VALUE="Beijing, Chongqing, Hong Kong, Urumqi, Taipei, Perth" />
                <STATIC_ROUTE_1 DEST="0.0.0.0" MASK="0.0.0.0" GATEWAY="0.0.0.0" />
                <STATIC_ROUTE_2 DEST="0.0.0.0" MASK="0.0.0.0" GATEWAY="0.0.0.0" />
                <STATIC_ROUTE_3 DEST="0.0.0.0" MASK="0.0.0.0" GATEWAY="0.0.0.0" />
                <IPV6_STATIC_ROUTE_1 IPV6_DEST="::" PREFIXLEN="0" IPV6_GATEWAY="::" ADDR_STATUS="INACTIVE" />
                <IPV6_STATIC_ROUTE_2 IPV6_DEST="::" PREFIXLEN="0" IPV6_GATEWAY="::" ADDR_STATUS="INACTIVE" />
                <IPV6_STATIC_ROUTE_3 IPV6_DEST="::" PREFIXLEN="0" IPV6_GATEWAY="::" ADDR_STATUS="INACTIVE" />
                <IPV6_PRIM_DNS_SERVER VALUE="::" />
                <IPV6_SEC_DNS_SERVER VALUE="::" />
                <IPV6_TER_DNS_SERVER VALUE="::" />
                <IPV6_DEFAULT_GATEWAY VALUE="::" />
                <IPV6_PREFERRED_PROTOCOL VALUE="N" />
                <IPV6_ADDR_AUTOCFG VALUE="N" />
                <IPV6_REG_DDNS_SERVER VALUE="N" />
                <DHCPV6_STATELESS_ENABLE VALUE="N" />
                <DHCPV6_STATEFUL_ENABLE VALUE="N" />
                <DHCPV6_RAPID_COMMIT VALUE="N" />
                <DHCPV6_DOMAIN_NAME VALUE="N" />
                <DHCPV6_SNTP_SETTINGS VALUE="N" />
                <DHCPV6_DNS_SERVER VALUE="N" />
                <ILO_NIC_AUTO_SELECT VALUE="DISABLED" />
                <ILO_NIC_AUTO_SNP_SCAN VALUE="0" />
                <ILO_NIC_AUTO_DELAY VALUE="90" />
                <ILO_NIC_FAIL_OVER VALUE="DISABLED" />
                <ILO_NIC_FAIL_OVER_DELAY VALUE="300" />
                <SNP_PORT VALUE="1" />
            </MOD_NETWORK_SETTINGS>
        </RIB_INFO>
        <RIB_INFO mode="write">
            <MOD_GLOBAL_SETTINGS>
                <SESSION_TIMEOUT VALUE="30" />
                <ILO_FUNCT_ENABLED VALUE="Y" />
                <F8_PROMPT_ENABLED VALUE="Y" />
                <F8_LOGIN_REQUIRED VALUE="N" />
                <RIBCL_STATUS VALUE="Y" />
                <WEBSERVER_STATUS VALUE="Y" />
                <WEBGUI_STATUS VALUE="Y" />
                <REMOTE_CONSOLE_STATUS VALUE="Y" />
                <VIRTUAL_MEDIA_STATUS VALUE="Y" />
                <HTTPS_PORT VALUE="443" />
                <HTTP_PORT VALUE="80" />
                <REMOTE_CONSOLE_PORT VALUE="179" />
                <VIRTUAL_MEDIA_PORT VALUE="179" />
                <SNMP_ACCESS_ENABLED VALUE="Y" />
                <SNMP_PORT VALUE="161" />
                <SNMP_TRAP_PORT VALUE="161" />
                <SSH_PORT VALUE="21" />
                <SSH_STATUS VALUE="Y" />
                <SERIAL_CLI_STATUS VALUE="3" />
                <SERIAL_CLI_SPEED VALUE="1" />
                <VSP_LOG_ENABLE VALUE="N" />
                <MIN_PASSWORD VALUE="8" />
                <AUTHENTICATION_FAILURE_LOGGING VALUE="3" />
                <AUTHENTICATION_FAILURE_DELAY_SECS VALUE="10" />
                <AUTHENTICATION_FAILURES_BEFORE_DELAY VALUE="1" />
                <LOCK_CONFIGURATION VALUE="N" />
                <RBSU_POST_IP VALUE="Y" />
                <ENFORCE_AES VALUE="N" />
                <IPMI_DCMI_OVER_LAN_ENABLED VALUE="N" />
                <REMOTE_SYSLOG_ENABLE VALUE="N" />
                <REMOTE_SYSLOG_PORT VALUE="514" />
                <REMOTE_SYSLOG_SERVER_ADDRESS VALUE="" />
                <ALERTMAIL_ENABLE VALUE="N" />
                <ALERTMAIL_EMAIL_ADDRESS VALUE="" />
                <ALERTMAIL_SENDER_DOMAIN VALUE="" />
                <ALERTMAIL_SMTP_PORT VALUE="25" />
                <ALERTMAIL_SMTP_SERVER VALUE="" />
                <ALERTMAIL_SMTP_SECURE_ENABLE VALUE="Y" />
                <ALERTMAIL_SMTP_AUTH_ENABLE VALUE="N" />
                <ALERTMAIL_SMTP_AUTH_USERNAME VALUE="" />
                <PROPAGATE_TIME_TO_HOST VALUE="N" />
                <IPMI_DCMI_OVER_LAN_PORT VALUE="623" />
            </MOD_GLOBAL_SETTINGS>
        </RIB_INFO>
        <DIR_INFO mode="write">
            <MOD_DIR_CONFIG>
                <DIR_AUTHENTICATION_ENABLED VALUE="Y" />
                <DIR_LOCAL_USER_ACCT VALUE="Y" />
                <DIR_SERVER_ADDRESS VALUE="contasa.com" />
                <DIR_SERVER_PORT VALUE="3269" />
                <DIR_OBJECT_DN VALUE="" />
                <DIR_USER_CONTEXT_1 VALUE="CN=ABC,DC=Contasa,DC=com" />
                <DIR_USER_CONTEXT_2 VALUE="CN=XYZ,DC=Contasa,DC=com" />
                <DIR_USER_CONTEXT_3 VALUE="CN=DDD,DC=Contasa,DC=com" />
                <DIR_USER_CONTEXT_6 VALUE="" />
                <DIR_USER_CONTEXT_7 VALUE="" />
                <DIR_USER_CONTEXT_8 VALUE="" />
                <DIR_USER_CONTEXT_9 VALUE="" />
                <DIR_USER_CONTEXT_10 VALUE="" />
                <DIR_USER_CONTEXT_11 VALUE="" />
                <DIR_USER_CONTEXT_12 VALUE="" />
                <DIR_USER_CONTEXT_13 VALUE="" />
                <DIR_USER_CONTEXT_14 VALUE="" />
                <DIR_USER_CONTEXT_15 VALUE="" />
                <DIR_ENABLE_GRP_ACCT VALUE="Y" />
                <DIR_GRPACCT1_NAME VALUE="Administrators" />
                <DIR_GRPACCT1_SID VALUE="" />
                <DIR_GRPACCT2_NAME VALUE="Authenticated Users" />
                <DIR_GRPACCT3_NAME VALUE="CN=ABC,DC=Contasa,DC=com" />
                <DIR_GRPACCT4_NAME VALUE="CN=XYZ,DC=Contasa,DC=com" />
                <DIR_GRPACCT5_NAME VALUE="CN=DDD,DC=Contasa,DC=com" />
                <DIR_GRPACCT6_SID VALUE="" />
                <DIR_KERBEROS_ENABLED VALUE="N" />
                <DIR_KERBEROS_REALM VALUE="" />
                <DIR_KERBEROS_KDC_ADDRESS VALUE="" />
                <DIR_KERBEROS_KDC_PORT VALUE="88" />
                <DIR_GENERIC_LDAP_ENABLED VALUE="N" />
            </MOD_DIR_CONFIG>
        </DIR_INFO>
        <RIB_INFO mode="write">
            <MOD_SNMP_IM_SETTINGS>
                <SNMP_ACCESS VALUE="Enable" />
                <SNMP_ADDRESS_1_ROCOMMUNITY VALUE="" />
                <SNMP_ADDRESS_2_ROCOMMUNITY VALUE="" />
                <SNMP_ADDRESS_3_ROCOMMUNITY VALUE="" />
                <SNMP_ADDRESS_1 VALUE="Server1.contasa.com" />
                <SNMP_ADDRESS_2 VALUE="Server1.contasa.com" />
                <SNMP_ADDRESS_3 VALUE="" />
                <SNMP_ADDRESS_3_TRAPCOMMUNITY VERSION="" VALUE="" />
                <SNMP_PORT VALUE="160" />
                <SNMP_TRAP_PORT VALUE="160" />
                <TRAP_SOURCE_IDENTIFIER VALUE="iLO Hostname" />
                <RIB_TRAPS VALUE="Y" />
                <OS_TRAPS VALUE="N" />
                <COLD_START_TRAP_BROADCAST VALUE="Y" />
                <SNMP_PASSTHROUGH_STATUS VALUE="N" />
                <WEB_AGENT_IP_ADDRESS VALUE="" />
                <CIM_SECURITY_MASK VALUE="3" />
                <SNMP_SYS_CONTACT VALUE="" />
                <SNMP_SYS_LOCATION VALUE="" />
                <AGENTLESS_MANAGEMENT_ENABLE VALUE="Y" />
                <SNMP_SYSTEM_ROLE VALUE="" />
                <SNMP_SYSTEM_ROLE_DETAIL VALUE="" />
            </MOD_SNMP_IM_SETTINGS>
        </RIB_INFO>
        <SERVER_INFO mode="write">
            <SET_HOST_POWER_SAVER HOST_POWER_SAVER="3" />
        </SERVER_INFO>
        <USER_INFO mode="write">
            <ADD_USER USER_NAME="admin" USER_LOGIN="admin" PASSWORD="%user_password%">
                <ADMIN_PRIV value="Y" />
                <REMOTE_CONS_PRIV value="Y" />
                <RESET_SERVER_PRIV value="Y" />
                <VIRTUAL_MEDIA_PRIV value="Y" />
                <CONFIG_ILO_PRIV value="Y" />
            </ADD_USER>
        </USER_INFO>
        <RIB_INFO mode="write"></RIB_INFO>
        <RIB_INFO mode="write">
            <SET_FEDERATION_MULTICAST>
                <MULTICAST_FEDERATION_ENABLED VALUE="No" />
                <MULTICAST_DISCOVERY_ENABLED VALUE="No" />
                <MULTICAST_ANNOUNCEMENT_INTERVAL VALUE="600" />
                <IPV6_MULTICAST_SCOPE VALUE="Site" />
                <MULTICAST_TTL VALUE="5" />
            </SET_FEDERATION_MULTICAST>
        </RIB_INFO>
        <SSO_INFO mode="write">
            <MOD_SSO_SETTINGS>
                <TRUST_MODE VALUE="DISABLED" />
                <USER_ROLE LOGIN_PRIV="Y" />
                <USER_ROLE REMOTE_CONS_PRIV="N" />
                <USER_ROLE VIRTUAL_MEDIA_PRIV="N" />
                <USER_ROLE RESET_SERVER_PRIV="N" />
                <USER_ROLE CONFIG_ILO_PRIV="N" />
                <USER_ROLE ADMIN_PRIV="N" />
                <OPERATOR_ROLE LOGIN_PRIV="Y" />
                <OPERATOR_ROLE REMOTE_CONS_PRIV="Y" />
                <OPERATOR_ROLE VIRTUAL_MEDIA_PRIV="Y" />
                <OPERATOR_ROLE RESET_SERVER_PRIV="Y" />
                <OPERATOR_ROLE CONFIG_ILO_PRIV="N" />
                <OPERATOR_ROLE ADMIN_PRIV="N" />
                <ADMINISTRATOR_ROLE LOGIN_PRIV="Y" />
                <ADMINISTRATOR_ROLE REMOTE_CONS_PRIV="Y" />
                <ADMINISTRATOR_ROLE VIRTUAL_MEDIA_PRIV="Y" />
                <ADMINISTRATOR_ROLE RESET_SERVER_PRIV="Y" />
                <ADMINISTRATOR_ROLE CONFIG_ILO_PRIV="Y" />
                <ADMINISTRATOR_ROLE ADMIN_PRIV="Y" />
            </MOD_SSO_SETTINGS>
        </SSO_INFO>
        <SERVER_INFO mode="write">
            <SERVER_AUTO_PWR VALUE="RESTORE" />
        </SERVER_INFO>
        <SERVER_INFO MODE="write">
            <SET_POWER_CAP POWER_CAP="0" />
        </SERVER_INFO>
    </LOGIN>
</RIBCL>

标签: powershell

解决方案


正如所评论的,我认为使用文本方法从 XML 文件中解析属性是一个坏主意。
最好让 PowerShell 为您解析它并选择您需要的属性:

$date      = (Get-Date).ToString("yyyyMMdd_HHmm")
$scriptDir = Split-Path $MyInvocation.MyCommand.Path  # or use: $PSScriptRoot
$outFile   = "$ScriptDir\ILOConfigData_$date.csv"
$servers   = Get-Content -Path .\servers.txt

$result = foreach ($server in $servers) {
    Write-Host "Gathering current ILO configuration for '$server'" 
    Invoke-Command -ComputerName $server -Credential $Credential -ScriptBlock {
        & "C:\Program Files\Hewlett Packard Enterprise\HPONCFG\hponcfg.exe" /a /w `
          "C:\Program Files\Hewlett Packard Enterprise\HPONCFG\Current_ILOConfig.xml" | Out-Null
    
        # load the xml the hponcfg.exe just created (PowerShell will parse it for you)
        $config = New-Object -TypeName System.Xml.XmlDocument
        $config.Load("C:\Program Files\Hewlett Packard Enterprise\HPONCFG\Current_ILOConfig.xml")

        # preselect the nodes for MOD_NETWORK_SETTINGS and DIR_USER_CONTEXT_1, DIR_USER_CONTEXT_2 etc.
        $networkSettings = $config.RIBCL.LOGIN.RIB_INFO.MOD_NETWORK_SETTINGS
        $userContext     = $config.RIBCL.LOGIN.DIR_INFO.MOD_DIR_CONFIG.ChildNodes | Where-Object {$_.Name -like 'DIR_USER_CONTEXT*' }
        # output a PSObject to be collected in variable $result
        [PsCustomObject] @{
            Server             = $env:COMPUTERNAME
            DNSName            = $networkSettings.DNS_NAME.VALUE
            DomainName         = $networkSettings.DOMAIN_NAME.VALUE
            IPAddress          = $networkSettings.IP_ADDRESS.VALUE
            SubnetMask         = $networkSettings.SUBNET_MASK.VALUE
            GateWay            = $networkSettings.GATEWAY_IP_ADDRESS.VALUE
            PrimaryDnsServer   = $networkSettings.PRIM_DNS_SERVER.VALUE
            SecondaryDnsServer = $networkSettings.SEC_DNS_SERVER.VALUE
            TertiaryDnsServer  = $networkSettings.TER_DNS_SERVER.VALUE
            TimeZone           = $networkSettings.TIMEZONE.VALUE
            # join the UserContext values that are not empty with a NewLine (or any other character you choose)
            UserContext        = ($userContext.VALUE | Where-Object { $_ -match '\S' }) -join [environment]::NewLine
        }

    }
}

# remove the extra properties Invoke-Command added
$result = $result | Select-Object * -ExcludeProperty "PSComputerName","RunspaceId","PSShowComputerName"
# save the result as CSV file
$result | Export-Csv -Path $outFile -NoTypeInformation -UseCulture

在 Excel 中打开时的结果:

在此处输入图像描述


推荐阅读