Массовое копирование 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, как должно.

Когда я возился с Path (потому что я думал, что это была причина сбоя), он иногда помещает файл в программные файлы с именем "ALM - Automatic Login Module", который является размером лицензии. файл.

Опять же, если я запускаю строку 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 файл журнала в удобочитаемом формате.


person Sha Gojyo    schedule 12.12.2016    source источник
comment
Почему нельзя использовать GPO? Это может показаться наиболее подходящим решением, поскольку вам не нужно вручную устанавливать файл лицензии каждый раз, когда новый компьютер подключается к сети (или восстанавливается старый и т. Д.).   -  person Bill_Stewart    schedule 12.12.2016
comment
Предпочтения групповой политики были бы лучшим способом сделать это, Элемент файла не совсем то, что вам нужно, и его можно отфильтровать для работы с x86 / x64.   -  person James C.    schedule 12.12.2016
comment
GPO на самом деле просто невозможно. Насколько я понял, Windows 2003 еще не поддерживает такого рода объекты групповой политики.   -  person Sha Gojyo    schedule 13.12.2016
comment
Я откатил [решенный] хак заголовка, здесь мы этого не делаем. Вопрос, вероятно, следует откатить дальше - он содержит и вопрос, и ответ, но, как вы обнаружили, у нас есть отдельный вид сообщений для ответов. Вы бы откатили это назад либо к первой версии, либо к промежуточной версии, в зависимости от вопроса? Если вы хотите перевести какой-либо промежуточный материал в собственно ответ, это может быть лучшим с точки зрения помощи в его сохранении (в нужном месте).   -  person halfer    schedule 23.12.2016


Ответы (3)


Хотя было бы лучше использовать объект групповой политики или запланированную задачу или, возможно, развернуть с помощью 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) {
...
person Jeff Zeitlin    schedule 12.12.2016
comment
Я уверен, что это лучше, но на данный момент кажется, что если test-path не работает, весь PS ломается и не действует так, как я намеревался. Я даже прокомментировал онлайн-проверку, потому что она продолжала терпеть неудачу в последнем операторе ELSE. По какой-то причине я не знаю, невозможно сделать более одного оператора IF за другим. Я очень надеюсь, что мне не придется прибегать к GOTO. Я опубликую редактирование моего основного сообщения с моими новыми результатами. - person Sha Gojyo; 13.12.2016

Я тоже голосую за 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\*"
......
} 

Также, с другой стороны, я надеюсь, что вы отформатировали содержимое вашего файла, чтобы вернуть массив. Если нет, просто разделите его "," и прочтите "Содержимое файла": Компьютер1, Компьютер2, Компьютер3.

и читать файл как массив напрямую

$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. 
person Prageeth Saravanan    schedule 12.12.2016
comment
По умолчанию Get-Content читает текстовый файл как массив - каждая строка в файле представляет элемент в массиве. Если каждый компьютер находится на отдельной строке, дополнительное форматирование не требуется. - person James C.; 12.12.2016

Окончательный вариант. Не мог заставить файл работать так, как я хотел.

Прибегает к 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

person Sha Gojyo    schedule 13.12.2016