Массовое копирование 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. 
Другие вопросы по тегам