Наконец-то я заработал функциональность моего скрипта, теперь я хочу сохранить в CSV, я использую | Export-CSV -path .\output.csv -Delimiter ";"
. но не могу получить нужные мне данные.
Я создаю глобальный пустой массив и пытаюсь добавить элементы в цикл foreach-object
но получить пустой CSV
я также запускаю свой foraech-object
в качестве задания и передаю | Export-CSV -path .\output.csv -Delimiter ";"
и получаю случайный набор чисел
как я могу получить свои данные в CSV?
Мой сценарий
Function Get-FileName{
[System.Reflection.Assembly]::LoadWithPartialName(“System.windows.forms”) | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = Get-Location
$OpenFileDialog.filter = “All files (*.*)| *.*”
$OpenFileDialog.ShowDialog() | Out-Null
$OpenFileDialog.filename
}
$Importfile = Get-FileName
$Clients = Get-Content $Importfile
$Do = $Clients | ForEach-Object -Parallel {
# CHECK IF PC IS IN AD AND STATUS OF PC IN AD ENABLED/DISABLED
$O = get-ADComputer -Identity $_ -Properties Enabled
if ($O."Enabled" -eq 'TRUE') {
#CHECK IF PC IS NETWORK ACCESSIBLE
if (Test-Connection -ComputerName $_ -Count 2 -Quiet){
try{
#GET LATEST KB PATCH INSTALLED
Get-HotFix -ComputerName $_ -Description 'Security Update' | Select-Object -Last 1 # tried to get csv from here and only capture what passes through here and not the catch or elses also tryed appending this to empty array
}
catch{
"$_;An error occurred."
}
}
else{
"$_;not on line "
}
}
else{
"$_;Disabled PC"
}
} -AsJob
$Do | Receive-Job -Wait # i tried " | Export-CSV -path .\output.csv -Delimiter ";" " and got random data
Привет, Lee_Dailey. Я забыл упомянуть, что вчера я обновился до PS 7.01 и изменю имена переменных. Я не знал, что РАБОТА была ключевым словом ... просто изучение PS без формального изучения - это больше практические занятия, потому что это нужно делать. спасибо за исправление
job
не ключевое слово ... это довольно конкретное существительное, используемое в *-Job
командлетах. использование его для имени $Var может привести к путанице, когда люди прочитают его и подумают... "я не вижу ничего общего с заданиями...". [усмехается] ///// Пожалуйста, УДАЛИТЕ тег ps3 и добавьте тег ps7, чтобы люди не путались в ваших тегах.
Сделанный ! Спасибо. Вы случайно не знаете PS 7???
Спасибо! К сожалению, я до сих пор не зашел в ps7 в это время. я не вижу ничего явно неправильного в вашем коде, хотя. ///// я бы, скорее всего, переключился на использование Invoke-Command
, так как вы можете дать ему блок сценария и список целевых систем ... и он будет запускать блок сценария на каждой системе параллельно. вы также можете отловить не ответивших с помощью -ErrorVariable
или сравнив ответивших с целевым списком.
Вам нужно передать (список) [pscustomobject] , а не [String]
, который требуется для ввода Export-Csv.
@iRon Я на самом деле новичок в написании сценариев для PS и PS, а английский не является моим родным языком. У вас есть ссылка на ресурс, на котором я могу узнать, о чем вы говорите, или вы можете объяснить проще, пожалуйста?
@Lee_Dailey К сожалению, для запуска Invoke-Command
требуется, чтобы WinRm был включен на клиентском ПК. Это не так, и мне пришлось бы включать службу вручную, поскольку сетевой администратор не будет создавать объект групповой политики ... с текущим сценарием я могу получить результат, который я хочу, но не могу создать CSV, шкафы, которые я получил, сделал это Get-HotFix -ComputerName $_ -Description 'Security Update' | Select-Object -Last | Export-Csv -path .\OutputFile.csv -Delimiter ";"
, но это фиксирует в CSV только те записи, которые попадают в это условие IF, а не ошибки или офлайн.
@Lee_Dailey Как я уже упоминал, я попытался создать глобальный пустой массив и попытался добавить данные в массив в зависимости от того, какое условие было выполнено, и в конце скрипта попытался поместить это в файл CSV, но массив никогда не заполнял информацию
@victorR - взгляните на это >>> Get-Help New-CimSessionOption -Parameter protocol
<<< и на это >>> Get-Help Invoke-Command -Parameter session
<<< //// это означает, что вы можете использовать DCOM вместо WSMan. если вы можете использовать командлеты WMI для доступа к этим системам... тогда вы можете использовать Invoke-Command
через New-CimSession
. [ухмылка]
@Lee_Dailey хорошо, он подключился к удаленному хосту, но я не могу запустить «invoke-command». cim-session
и invoke-method
- новый монстр, которого мне нужно исследовать ... можете ли вы привести пример запуска invoke-command
, хотя, пожалуйста, cimsession
@victorR — используйте New-CimSessionOption
, чтобы установить протокол. затем используйте New-CimSession
, чтобы создать сеансы для всех [или группы] целей. затем используйте параметр -Session
для Invoke-Command
, чтобы указать ему использовать коллекцию сеансов по мере необходимости. наконец, подайте блок сценария на вызов I-C
. что должен сделать это. в настоящее время у меня нет ничего, чтобы проверить это ... только моя единственная домашняя система.
@Lee_Dailey Я попробовал это, и вот что у меня получилось " Invoke-Command -session $ses {get-hotfix} Invoke-Command: Cannot bind parameter 'Session'. Cannot convert the "CimSession: PC-w032" value of type "Microsoft.Management.Infrastructure.CimSession" to type "System.Management.Automation.Runspaces.PSSession"
. это было после того, как я создал новую сессию с протоколом DCOM
@victorR - я вижу, что iRon опубликовал рабочий ответ. так как у меня нет никакого способа протестировать проблемы CIMSession, я предлагаю оставить это и использовать рабочее решение, представленное iRon.
Как человек «новичок в PS», я рекомендую вам сделать несколько шагов назад и упростить вещи, а также удалить переключатель -Parallel
, который может скрыть вывод.
Как уже отмечалось, для командлета Export-Csv требуется поток только элементов [pscustomobject], вы не можете комбинировать это со строками (например, "$_;An error occurred."
) или объектом с другими свойствами.
См.: Не все свойства отображаются и #13906 Добавить параметр -UnifyProperties в Select-Object
function UniteProperties { # https://github.com/PowerShell/PowerShell/issues/13906#issuecomment-717480544
[System.Collections.Generic.List[string]] $propNames = @()
[System.Collections.Generic.HashSet[string]] $hashSet = @()
$inputCollected = @($input)
$inputCollected.ForEach({
foreach ($name in $_.psobject.Properties.Name) {
if ($hashSet.Add($name)) { $propNames.Add($name) }
}
})
$inputCollected | Select-Object $propNames
}
$Do = 2, 3, 0, 5 | ForEach-Object -Parallel {
Try {
[pscustomobject]@{ Name = "Client$_"; HotFix = 1/$_ } # some standard HotFix results
}
Catch {
[pscustomobject]@{ message = "$_;An error occurred." }
}
}
$Do | UniteProperties | ConvertTo-Csv # Or ... Export-Csv
"Name","HotFix","message"
"Client2","0.5",
"Client3","0.3333333333333333",
,,"Attempted to divide by zero.;An error occurred."
"Client5","0.2",
команда
Foreach-Object -Parallel
недоступна, если у вас нет PS7+. вы говорите, что используете ps3 ... так что вы получаете какие-либо ошибки от этого неправильного использования? [усмехается] ///// также использование$Job
для имени переменной несколько вводит в заблуждение, поскольку существуют командлеты PSJob. я настоятельно рекомендую вам НИКОГДА не использовать ключевые слова или существительные командлетов специального назначения для имен переменных.