Прямо сейчас у меня есть файл CSV, который содержит более 3800 записей. Этот файл содержит список имен серверов, за которым следует аббревиатура, указывающая, является ли сервер сервером Windows, сервером Linux и т. д. Файл также содержит комментарии или документацию, где каждая строка начинается с символа «#», что означает, что это комментарий. На данный момент у меня есть следующее.
$file = Get-Content .\allsystems.csv
$arraysplit = @()
$arrayfinal = @()
[int]$windows = 0
foreach ($thing in $file){
if ($thing.StartsWith("#")) {
continue
}
else {
$arraysplit = $thing.Split(":")
$arrayfinal = @($arraysplit[0], $arraysplit[1])
}
}
foreach ($item in $arrayfinal){
if ($item[1] -contains 'NT'){
$windows++
}
else {
continue
}
}
$windows
Цель этого сценария - подсчитать общее количество серверов Windows. Моя проблема в том, что первый блок «foreach» работает нормально, но второй приводит к тому, что «$ Windows» становится 0. Честно говоря, я не уверен, почему это не работает. Вот две примерные строки данных:
example:LNX
example2:NT





$arrayfinal = @($arraysplit[0], $arraysplit[1])
Это заменяет массив при каждом запуске.
Замена его на += дала еще одну проблему. Он просто добавлял каждый отдельный элемент. Я использовал информацию из этого поста, чтобы исправить это, как бы форсируя 2d-массив: Как создать массив массивов в PowerShell?.
$file = Get-Content .\allsystems.csv
$arraysplit = @()
$arrayfinal = @()
[int]$windows = 0
foreach ($thing in $file){
if ($thing.StartsWith("#")) {
continue
}
else {
$arraysplit = $thing.Split(":")
$arrayfinal += ,$arraysplit
}
}
foreach ($item in $arrayfinal){
if ($item[1] -contains 'NT'){
$windows++
}
else {
continue
}
}
$windows
1
Я также изменил файл и добавил больше экземпляров NT и другого случайного мусора. Кажется, все работает нормально.
Я бы не стал делать еще один цикл ForEach для увеличения количества экземпляров. Ваш $ arrayfinal также перезаписывается каждый раз, поэтому я использовал ArrayList.
$file = Get-Content "E:\Code\PS\myPS\2018\Jun\12\allSystems.csv"
$arrayFinal = New-Object System.Collections.ArrayList($null)
foreach ($thing in $file){
if ($thing.StartsWith("#")) {
continue
}
else {
$arraysplit = $thing -split ":"
if ($arraysplit[1] -match "NT" -or $arraysplit[1] -match "Windows")
{
$arrayfinal.Add($arraysplit[1]) | Out-Null
}
}
}
Write-Host "Entries with 'NT' or 'Windows' $($arrayFinal.Count)"
Я не уверен, хотите ли вы сохранить 'Example', 'example2' ... поэтому я пропустил добавление их в arrayfinal, предполагая, что цель состоит в том, чтобы подсчитать появления "NT" или "Windows"
если цель состоит в том, чтобы подсчитать серверы Windows, зачем вам массив?
ты не можешь просто сказать что-нибудь вроде
foreach ($thing in $file)
{
if ($thing -notmatch "^#" -and $thing -match "NT") { $windows++ }
}
The goal of this script is to count the total number of Windows servers.
Я бы посоветовал простой способ: использовать специально созданные для этого командлеты.
$csv = Get-Content -Path .\file.csv |
Where-Object { -not $_.StartsWith('#') } |
ConvertFrom-Csv
@($csv.servertype).Where({ $_.Equals('NT') }).Count
# Compatibility mode:
# ($csv.servertype | Where-Object { $_.Equals('NT') }).Count
Замените servertype и 'NT' тем, что называется заголовком / значением.
Дальнейшее упрощение:
-cmatch '^[^#].*?NT'