Windows Powershell Scripting

Hi, could someone assist with an example of a powershell script that I could edit for my network environment?

I have a need to update (overwrite) a file on all PC's in a particular department in our MS AD environment, the path I need to drop the file into is C:\Program Files\xxx\xxx.

The share file will come off a shared network drive that the department already have access to, I was going to do it via a batch file at logon but have concerns that it will not overwrite the existing file without user intervention.  The users machines are W7 Pro's and have tighter security than most machines so additional credentials might be needed and I wouldn't want that visible to the users.

So is there a script that I can edit and use to achieve this and what is the best way to execute it.  It would be good to have it run during the day rather than at logon if possible by being pushed to the PC's?

Thanks for any advise or assistance in advance.
mercuriousu2Asked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
oBdAConnect With a Mentor Commented:
Logon would not work, as users don't have Write permissions in Program Files.
You can use this to push the file from an administrative machine. It will log which machines were processed, so you can call it several times and it will only reprocess machines were a former attempt failed.
$SearchBase = "OU_Wherever,DC=contoso,DC=com"
$SourceFile = 'C:\Temp\test.txt'
$TargetFolder = 'C:\Program Files'

$ScriptItem = Get-Item -Path $MyInvocation.MyCommand.Path
$CsvPath = Join-Path -Path $ScriptItem.DirectoryName -ChildPath "$($ScriptItem.BaseName).csv"
$Csv = If (Test-Path -Path $CsvPath) {
	"Continuing from  $($CsvPath) ..." | Write-Host -ForegroundColor White
	Import-Csv -Path $CsvPath
} Else {
	"Retrieving AD computer from $($SearchBase) ..." | Write-Host -ForegroundColor White
	Get-ADComputer -Properties Name -Filter "(Enabled -eq 'True') -and (OperatingSystem -like 'Windows 7*')" -SearchBase $SearchBase |
		Select-Object Name, DNSHostName, @{n='Processed'; e={'False'}},  @{n='Error'; e={''}}, DistinguishedName |
		Sort-Object -Property Name
}
ForEach ($Computer In $Csv) {
	"Processing $($Computer.Name) ... " | Write-Host -ForegroundColor White -NoNewline
	If ($Computer.Processed -eq 'True') {
		'already processed.' | Write-Host -ForegroundColor Green
	} Else {
		If (Test-Connection -ComputerName $Computer.DNSHostName -Count 2 -Quiet) {
			'online, copying ... ' | Write-Host -ForegroundColor Yellow -NoNewline
			Try {
				Copy-Item -Path $SourceFile -Destination "\\$($Computer.DNSHostName)\$($TargetFolder.Replace(':', '$'))" -Force -ErrorAction Stop
				$Computer.Processed = 'True'
				'OK.' | Write-Host -ForegroundColor Green
			} Catch {
				$Computer.Error = $_.Exception.Message
				$Computer.Error | Write-Host -ForegroundColor Red
			}
		} Else {
			$Computer.Error = 'Offline'
			$Computer.Error | Write-Host -ForegroundColor Red
		}
	}
}
$Csv | Export-Csv -Path $CsvPath -NoTypeInformation
$Csv | Format-Table -AutoSize

Open in new window

1
 
mercuriousu2Author Commented:
Hi, thank you for providing that. I assume these are the only editable fields I need to edit:

$SearchBase = "OU_Wherever,DC=contoso,DC=com"
$SourceFile = 'C:\Temp\test.txt'
$TargetFolder = 'C:\Program Files'

Am I correct in assuming that the searchbase is the OU with the group membership in?

Does this run seamless to the user, also where can I edit the path to get a completed or failed csv or does the script write it to the source file destination?

Thanks
0
 
oBdACommented:
$SearchBase is the OU where the computer objects to process are.
The csv file will be stored in the script's folder, with the script's name, and the extension '.csv'.
0
Improved Protection from Phishing Attacks

WatchGuard DNSWatch reduces malware infections by detecting and blocking malicious DNS requests, improving your ability to protect employees from phishing attacks. Learn more about our newest service included in Total Security Suite today!

 
mercuriousu2Author Commented:
Ok, that failed and I think the was because the OU of the group needed is users and not Computer names.  We dont have a OU for specific users PC's as the change out rate at time would make it hard to keep updated.

Is there an addition that can be made so the script picks up the logged on user at the PC at all?

Thanks
0
 
oBdACommented:
You're trying to deliver a file to computers - where do users come into play here? If it's under Program Files, the program will be installed on the machine regardless of the user logging on at some point.
0
 
mercuriousu2Author Commented:
Yup, but I dont have the user machines in an OU specific just for them, just one OU for computers for the entire company :-(
0
 
oBdACommented:
Then you need to generate a text file of computer names (one name per line) and use this script:
$ComputerList = 'C:\Temp\ComputerList.txt'
$SourceFile = 'C:\Temp\test.txt'
$TargetFolder = 'C:\Program Files'

$ScriptItem = Get-Item -Path $MyInvocation.MyCommand.Path
$CsvPath = Join-Path -Path $ScriptItem.DirectoryName -ChildPath "$($ScriptItem.BaseName).csv"
$Csv = If (Test-Path -Path $CsvPath) {
	"Continuing from  $($CsvPath) ..." | Write-Host -ForegroundColor White
	Import-Csv -Path $CsvPath
} Else {
	"Retrieving AD computer from file '$($ComputerList)' ..." | Write-Host -ForegroundColor White
	Get-Content -Path $ComputerList | 
		Select-Object @{n='Name'; e={$_.Split('.')[0]}}, @{n='DNSHostName'; e={$_}}, @{n='Processed'; e={'False'}},  @{n='Error'; e={''}}, DistinguishedName |
		Sort-Object -Property Name
}
ForEach ($Computer In $Csv) {
	"Processing $($Computer.Name) ... " | Write-Host -ForegroundColor White -NoNewline
	If ($Computer.Processed -eq 'True') {
		'already processed.' | Write-Host -ForegroundColor Green
	} Else {
		If (Test-Connection -ComputerName $Computer.DNSHostName -Count 2 -Quiet) {
			'online, copying ... ' | Write-Host -ForegroundColor Yellow -NoNewline
			Try {
				Copy-Item -Path $SourceFile -Destination "\\$($Computer.DNSHostName)\$($TargetFolder.Replace(':', '$'))" -Force -ErrorAction Stop
				$Computer.Processed = 'True'
				'OK.' | Write-Host -ForegroundColor Green
			} Catch {
				$Computer.Error = $_.Exception.Message
				$Computer.Error | Write-Host -ForegroundColor Red
			}
		} Else {
			$Computer.Error = 'Offline'
			$Computer.Error | Write-Host -ForegroundColor Red
		}
	}
}
$Csv | Export-Csv -Path $CsvPath -NoTypeInformation
$Csv | Format-Table -AutoSize

Open in new window

0
 
mercuriousu2Author Commented:
Excellent, many thanks. I will be able to amend this for future use as well :-)

Appreciate the assistance
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.