I'm trying to copy a license file to all domain joined computers, and i am only able to use PowerShell. GPO or even (GPO) scheduled task is a no-go, because these don't seem to be possible yet within a Server 2003 environment. The application this is regarding is already installed, and only the license file needs to be overwritten.
i am hoping to achieve: - check if online, else skip - check for 32b folder location, if exist, copy, else skip - check for 64b folder location, if exist copy, else skip - write every computers' result to a log file so i can prune successful
1st attempt;
Code i have currently:
$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" } } }
I've tried some minor variations, but i can't seem to get anywhere. Also the logging needs yet to be created.
Using myself as a test target, having run above variables, and using single commands;
$TestPath32 = Test-Path -path "\$computer\$dest32b*"
Returns: True
Copy-Item $source -Destination "\$computer\$dest32b" -recurse -force -verbose
is successful, and copies the file
Running the PowerShell at the moment complains about the last ELSE statement.
But most of the time it failed not recognizing i don't have a 64b folder, and it either gives an error, or places a file, with the directory as the filename.
I'm at a loss and have now tried so many things i'm afraid of braking the little that i've got.
2nd attempt;
I have edited the code and commented out some parts, just to get a working > model to progress from there.
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" # } #} }
Now returns :
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
i can assure you i DO have the 32b path. The copy-item doesn't place the file. i DO NOT have the 64b path obviously, and i feel it breaks on this instead of just neatly returning $false like it should.
When i mess arround with he Path (because i thought that was the reason for the failure), it sometimes places a file in Program Files named "ALM - Automatic Login Module" which is the size of the license file.
Again, if i run the line
Copy-Item $source -Destination "\\$computer\$dest32b\"
as stand-alone, it DOES copy the file.
3rd attempt, now working;
$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
}
}
}
The use of !$ totally went over my head, and i was supposed to work from a point of:
IF NOT, THEN, ELSE
Now the script skips folders not present, havn't been able to test a down computer yet, but i assume this now works also.
Now all i need to figure out, is how to log the output into 1 logfile, in a readable format
Final version. Couldn't get out-file to work like i wanted to.
Resorted to Start-Transcript. Had to put Get-Content at the end to format the output to something that was readable.
#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
The actual solution as to why this works = Test-Path -pathtype container