2

我正在尝试将许可证文件复制到所有加入域的计算机,并且我只能使用 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 = 测试路径 -path "\$computer\$dest32b*"

返回:真

复制项目 $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\"作为独立运行该行,它会复制文件。


第三次尝试,现在工作;

$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 个日志文件中

4

3 回答 3

0

正如评论中提到的,我也投票支持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. 
于 2016-12-12T15:56:59.273 回答
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) {
...
于 2016-12-12T15:58:13.527 回答
0

最终版本。无法像我想要的那样工作。

诉诸开始-成绩单。必须将 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

于 2016-12-13T13:42:14.433 回答