PowerShell批量复制到具有多个检查的域计算机

时间:2016-12-12 15:34:46

标签: powershell if-statement cross-domain copy-item

我正在尝试将许可证文件复制到所有已加入域的计算机, 我只能使用PowerShell。 GPO甚至(GPO)计划任务是不可行的,因为在Server 2003环境中似乎不可能执行这些任务。 已安装此应用程序,只需要覆盖许可证文件。

我希望实现: - 检查是否在线,否则跳过 - 检查32b文件夹位置,如果存在,复制,否则跳过 - 检查64b文件夹位置,如果存在副本,否则跳过 - 将每台计算机的结果写入日志文件,以便我可以修剪成功

第一次尝试;

  

我目前的代码:

$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文件夹,并且它给出了一个错误,或者放置了一个文件,目录作为文件名。

     

我很茫然,现在已经尝试了很多东西,我害怕制造我所拥有的那些东西。

第二次尝试;

  

我已经编辑了代码并注释掉了一些部分,只是为了得到一个工作>模型从那里开始。

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。

     

当我把它与路径混乱时(因为我认为这是失败的原因),它有时会在名为“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 个答案:

答案 0 :(得分:0)

我投票赞成 GPO ,正如评论中所提到的,你一定要考虑到这一点。

但是,如果它对你没有帮助, 你的$ TestPath32&amp;在分配单个计算机值之前,将评估$ TestPath64变量。我只是为null,因此两者都是$ false。你可以简单地在for循环中移动它们,

foreach ($computer in $computers) {    
    if (test-Connection -Cn $computer -quiet) {
       $TestPath32 = Test-Path -path "\\$computer\$dest32b\*"
       $TestPath64 = Test-Path -path "\\$computer\$dest64b\*"
......
} 

另一方面,我希望您已格式化文件的内容以返回数组。如果不是,你只需用&#34;,&#34;并阅读 文件内容: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. 

答案 1 :(得分:0)

虽然使用GPO或计划任务会更好,或者如果你已经使用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) {
...

答案 2 :(得分:0)

最终版本。 无法像我想的那样让外出工作。

使用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