@Digsecman

Не срабатывает скрипт доступности доменных пк. Почему?

Пытаюсь получить список всех пк с сохранением в csv добавив поле-флаг "установлено", скрипт должен перебирать строчки в файле в поисках "не установлено" и "доступно" и если комп онлайн тогда инсталить если нет тогда пинговать и как только он будет в сети тогда установить по.
кроме того проверяется есть ли папка fusion, если нет тогда копируется содержимое с сетевой шары домена
помогите пожалуйста кто разбирается синтаксис поправить чтобы отрабатывало.

$dest="\\$all\C$\fusion"
$sourcefile = "\\WIN\c$\fusion\*"
$all=Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(!userAccountControl:1.2.840.113556.1.4.803:=8192))" -Properties name | Sort).name|Import-csv C:\Users\user\Desktop\list.csv|
foreach ($comp in $all) {
  if (-not $comp.installed -and(test-connection $comp.name) -and(-not (test-path "C:\fusion\*"))) { 
if (!(Test-Path -path $dest))
    {
        New-Item $dest -Type Directory
    }
    Copy-Item -Path $sourcefile -Destination $dest;
     {Invoke-command -computername $comp.name -ScriptBlock –ThrottleLimit 120 {powershell "& 'C:\fusion\fusion.bat'"} 
     }
     $comp.installed=$true
  }
}
$all | export-csv C:\Users\user\Desktop\installed.csv
  • Вопрос задан
  • 92 просмотра
Решения вопроса 1
hekkaaa
@hekkaaa
C#/.NET Developer
Привет.
Прошу правильно понять меня. У Вас плохо написан скрипт. Такая реализация имеет место быть, но чем проще и очевиднее пишете тем лучше. (лично мое мнение). Да и судя по всему вы сами запутались в нем же.

Переменная $all получает данные из AD по фильтру и еще что то импортирует. - Тут ок, Вам виднее что вы хотите найти.
Но вот ошибка в скобках 4 строчки вероятно в выделенном месте:
$all=Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(!userAccountControl:1.2.840.113556.1.4.803:=8192))" -Properties (name | Sort).name|Import-csv C:\Users\user\Desktop\list.csv

Только обратите внимание, что Вы дальше делаете конвеер foreach. Зачем тут конвеер если данные находятся в переменной.
В самом foreach только if содержится.
Так можно делать, но не удивляйтесь что дальше крашится будет еще активнее. Вероятнее всего в ветке Test-Path -path $dest и далее. У вас нет ловли ошибок и работы с ними. Используйте try catch.

Как минимум Хост может не ответить Вам на Test-Path , а еще туча ошибок при копировании (а есть ли папка назначения на данном хосте куда вы батник копируете? Это тоже стоит проверить) или Invoke-command . MaxKozlov не даст соврать, на этих командлетах можно много говна поймать.

Ну и концовка "$all | export-csv C:\Users\user\Desktop\installed.csv" - дело ваше как вы будете отслеживать на каких машинах взлетел скрипт на каких нет, но рекомендую заморочится в логировании.

Итог: Перепишите скрипт с нуля. У Вас сложная фильтрация в которой вы сами видимо запутались. Разбейте ее на 2-3 шага в отдельные переменные. Лучше так чем часами сидеть и не понимать ничего.
Сделайте полноценные хотя бы if else, ведь ошибки неизбежны.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@GaryManshow
Привет, я обычно использую ADSISearch вместо Get-ADComputer
если много компьютеров используйте параллельную обработку:

$credential = Get-Credential DOMAIN\user
$Domain = New-Object -TypeName System.DirectoryServices.DirectoryEntry -ArgumentList $(([adsisearcher]"").SearchRoot.Path), ($credential.UserName), $($credential.GetNetworkCredential().Password)
# поиск ADSI
$Searcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$Searcher.SearchRoot = $Domain
$Searcher.Filter = "(&(objectCategory=computer)(operatingSystem=Windows*)(!(operatingSystem=*server*))(!(userAccountControl:1.2.840.113556.1.4.803:=8192)))"
$out = $Searcher.FindAll().Properties.name | ForEach-Object {
	# пингуем
	Test-Connection -ComputerName $_ -Count 1 -AsJob  -ThrottleLimit 128
} | Get-Job | Receive-Job -Wait | Where-Object { $_.StatusCode -eq 0 } | Select-Object Address | ForEach-Object {
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы