Массовое копирование PowerShell на доменные компьютеры с несколькими проверками
Я пытаюсь скопировать файл лицензии на все компьютеры, присоединенные к домену, и могу использовать только PowerShell. Запланированная задача GPO или даже (GPO) не требуется, поскольку в среде Server 2003 это пока невозможно. Это приложение уже установлено, и необходимо перезаписать только файл лицензии.
я надеюсь добиться: - проверить, подключен ли он к сети, иначе пропустить - проверить местоположение папки 32b, если существует, скопировать, иначе пропустить - проверить местоположение папки 64b, если существует копия, иначе пропустить - записать результаты всех компьютеров в файл журнала так что я могу обрезать удачно
1-я попытка;
Код, который я имею в настоящее время:
$computers = gc "c:\temp\computers.txt" $source = "c:\temp\almmodule.lic" $dest32b = 'c$\program files (x86)\ALM - Automatic Login Module' $dest64b = 'c$\program files\ALM - Automatic Login Module' $TestPath32 = Test-Path -path "\\$computer\$dest32b\*" $TestPath64 = Test-Path -path "\\$computer\$dest64b\*" foreach ($computer in $computers) { if (test-Connection -Cn $computer -quiet) { IF (!$TestPath32) { Copy-Item $source -Destination "\\$computer\$dest32b" -recurse -force -verbose} ELSE { "$computer' 32b folder not found. Skipping"} IF (!$TestPath64) { Copy-Item $source -Destination "\\$computer\$dest64b" -recurse -force -verbose} ELSE {"$computer 64b folder not found. Skipping"} ELSE { "$computer is not online" } } }
Я пробовал небольшие изменения, но, похоже, никуда не денусь. Также регистрация должна быть еще создана.
Использование себя в качестве цели тестирования, выполнение выше переменных и использование отдельных команд;
$ TestPath32 = Test-Path -path "\ $ computer \ $ dest32b *"
Возвращает: True
Copy-Item $ source -Destination "\ $ computer \ $ dest32b" -recurse -force -verbose
успешно, и копирует файл
Запуск PowerShell в данный момент жалуется на последнее утверждение ELSE.
Но большую часть времени он не смог распознать, что у меня нет папки 64b, и он либо выдает ошибку, либо помещает файл с каталогом в качестве имени файла.
Я в растерянности и сейчас перепробовал так много вещей, что боюсь тормозить то, что у меня есть.
2-я попытка;
Я отредактировал код и закомментировал некоторые части, просто чтобы получить от этого работающую модель.
foreach ($computer in $computers) { $TestPath32 = Test-Path "\\$computer\$dest32b\*" $TestPath64 = Test-Path "\\$computer\$dest64b\*" # if (test-Connection -Cn $computer -quiet) { IF (!$TestPath32) { Copy-Item $source -Destination "\\$computer\$dest32b\" -recurse -force -verbose} ELSE {"$computer' 32b folder not found. Skipping"} IF (!$TestPath64) { Copy-Item $source -Destination "\\$computer\$dest64b\" -recurse -force -verbose} ELSE {"$computer 64b folder not found. Skipping"} # ELSE { # "$computer is not online" # } #} }
Теперь возвращается:
PS C:\windows\system32> C:\Temp\ALM 2016 LIC copy.ps1 L2016010' 32b folder not found. Skipping VERBOSE: Performing operation "Copy File" on Target "Item: C:\temp\almmodule.lic Destination: \\L2016010\c$\program files\ALM - Automatic Login Module\". Copy-Item : De syntaxis van de bestandsnaam, mapnaam of volumenaam is onjuist. At C:\Temp\ALM 2016 LIC copy.ps1:14 char:12 + Copy-Item <<<< $source -Destination "\\$computer\$dest64b\" -force -verbose} + CategoryInfo : NotSpecified: (:) [Copy-Item], IOException + FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.CopyItemCommand
Я могу заверить вас, у меня есть путь 32B. Копия не помещает файл. у меня, очевидно, нет пути 64b, и я чувствую, что он ломается на этом вместо того, чтобы просто аккуратно возвращать $false, как должно.
Когда я путаюсь с Путь (потому что я думал, что это было причиной сбоя), он иногда помещает файл в Program Files с именем "ALM - Модуль автоматического входа", который является размером файла лицензии.
Опять же, если я бегу по линии
Copy-Item $source -Destination "\\$computer\$dest32b\"
как отдельный, он копирует файл.
3-я попытка, сейчас работает;
$computers = gc "c:\temp\computers.txt"
$source = "c:\temp\almmodule.lic"
$dest32b = 'c$\program files (x86)\ALM - Automatic Login Module'
$dest64b = 'c$\program files\ALM - Automatic Login Module'
foreach ($computer in $computers) {
$TestUp = test-Connection -Cn $computer -quiet
$TestPath32 = Test-Path -pathType container "\\$computer\$dest32b"
$TestPath64 = Test-Path -pathType container "\\$computer\$dest64b"
IF (!$TestUp) {
write-host "$computer is not online"
} ELSE {
IF (!$TestPath32){
write-host "$computer' 32b folder not found. Skipping"
} ELSE {
Copy-Item $source -Destination "\\$computer\$dest32b\" -force -verbose
}
IF (!$TestPath64){
write-host "$computer 64b folder not found. Skipping"
} ELSE {
Copy-Item $source -Destination "\\$computer\$dest64b\" -force -verbose
}
}
}
Использование!$ Полностью прошло через мою голову, и я должен был работать с точки зрения:
Если нет, то иначе
Теперь скрипт пропускает папки, которых нет, еще не смог протестировать сбойный компьютер, но я предполагаю, что теперь это работает.
Теперь все, что мне нужно выяснить, это как записать вывод в 1 лог-файл, в читаемом формате
3 ответа
Окончательный вариант. Не могу получить доступ к работе, как я хотел.
Прибегает к Start-Transcript. Пришлось поставить Get-Content в конце, чтобы отформатировать вывод во что-то, что было читабельным.
#set-executionpolicy RemoteSigned
$computers = gc "c:\temp\computers.txt"
$source = "c:\temp\almmodule.lic"
$dest32b = 'c$\program files (x86)\ALM - Automatic Login Module'
$dest64b = 'c$\program files\ALM - Automatic Login Module'
Start-Transcript -path C:\temp\ALM-Log.txt -append
foreach ($computer in $computers) {
$TestUp = test-Connection -Cn $computer -quiet
$TestPath32 = Test-Path -pathType container "\\$computer\$dest32b"
$TestPath64 = Test-Path -pathType container "\\$computer\$dest64b"
IF (!$TestUp) {
write-host "$computer is not online`r"
} ELSE {
IF (!$TestPath32){
write-host "$computer' 32b folder not found. Skipping`r"
} ELSE {
Copy-Item $source -Destination "\\$computer\$dest32b\" -force -verbose
}
IF (!$TestPath64){
write-host "$computer 64b folder not found. Skipping`r"
} ELSE {
Copy-Item $source -Destination "\\$computer\$dest64b\" -force -verbose
}
}
}
Stop-Transcript
$log = Get-Content C:\temp\ALM-Log.txt
$log > c:\temp\ALM-Log.log
Фактическое решение относительно того, почему это работает = Test-Path -pathtype container
Хотя использование объекта групповой политики или запланированной задачи было бы лучше, или, возможно, развертывание с SCCM, если оно у вас есть, в ваших ограничениях есть ответ. У вас есть правильная основная идея, но перенесите свои задания $TestPath32
а также $TestPath64
в foreach
цикл:
...
foreach ($computer in $computers) {
if (test-Connection -Cn $computer -quiet) {
$TestPath32 = Test-Path -path "\\$computer\$dest32b\*"
$TestPath64 = Test-Path -path "\\$computer\$dest64b\*"
IF (!$TestPath32) {
...
Я также голосую за GPO, как уже упоминалось в комментариях, вы обязательно должны это учитывать.
Однако, если это вам не поможет, переменные $TestPath32 и $TestPath64 оцениваются перед назначением значений для вашего отдельного компьютера. Я был бы просто нулем, и, следовательно, оба будут $false. Вы можете просто переместить их в свой цикл for,
foreach ($computer in $computers) {
if (test-Connection -Cn $computer -quiet) {
$TestPath32 = Test-Path -path "\\$computer\$dest32b\*"
$TestPath64 = Test-Path -path "\\$computer\$dest64b\*"
......
}
Также, с другой стороны, я надеюсь, что вы отформатировали содержимое вашего файла так, чтобы он возвращал массив. Если нет, просто разделите его с помощью "," и прочитайте содержимое файла: Computer1,Computer2,Computer3
и читать файл как массив напрямую
$computers = Get-Content 'c:\temp\computers.txt' # It will read it as an array only. YOu do not need any additional formatting in this case.