tri_94 Posted March 8, 2019 Posted March 8, 2019 Hi there I've been working on a script to allow me to export a ou to csv. Then if wanted run gp update on any pcs that are online from that ou. I've got part of it working. But am stumbling because the export from Ad gives heading name "Name" and not ComputerName which my test connectivity seems to want. I've not tested the invoke gp update part. Anyone any ideas. I know its possible not the neatest or best way of doing it. I did even try renaming the header in the script but that seems to mess everything up. Thanks [system.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null $OU = [Microsoft.VisualBasic.Interaction]::InputBox($Inputbox, "Active Directory", "$OU") $Inputbox = "Please enter required OU" $file = "D:\$OU.csv" $online = "D:\$OU-Online.csv" Get-ADComputer -Filter * -SearchBase "$OU" | Select-Object Name | Export-CSV $file -NoTypeInformation #Import-Csv $file | #Select-Object @{ expression={$_.Name}; label='ComputerName' } | #Export-Csv -NoTypeInformation $file Add-Type -AssemblyName PresentationCore,PresentationFramework $ButtonType = [system.Windows.MessageBoxButton]::YesNo $MessageIcon = [system.Windows.MessageBoxImage]::Question $MessageBody = "Would you like to force a Group Policy update to this OU ?" $Result = [system.Windows.MessageBox]::Show($MessageBody,$MessageTitle,$ButtonType,$MessageIcon) switch ($Result) { 'Yes' { Get-Content $file | ForEach-Object { New-Object -TypeName PSCustomObject -Property @{ Name = $_ 'Ping Status' = Test-Connection -ComputerName $_ -Quiet -Count 1 } } | Export-Csv -Path "$online" -NoTypeInformation Get-Content $online | ForEach-Object { Invoke-GPUpdate -Computer $Computer.Name -RandomDelayInMinutes 0 -force; "Refreshing Host $Computer." | Write-Host } } 'No' { #Exit } }
glen_j Posted March 8, 2019 Posted March 8, 2019 Can't help with the coding but if you are trying to update group policy on computers in an OU you can now right click on the OU in GPMC.msc and update group policy.
ThomL Posted March 8, 2019 Posted March 8, 2019 Do thes computer names need to be written to file like you're doing it etc? I'm off to lunch but when i get back i'm happy to have a crack at fixing it if no one else has helped
tri_94 Posted March 8, 2019 Author Posted March 8, 2019 Not bothered how it works. I need to export from ad via ou and then test which are online and then prompt to update and then run the invoke command against all online pcs Would be nice to have a list of which have been updated and which were offline. Thanks
ThomL Posted March 8, 2019 Posted March 8, 2019 What output do you want? anything to the powershell session or just write a csv with the info? Both maybe?
ThomL Posted March 11, 2019 Posted March 11, 2019 forgot about this, sorry! Its not working how I wanted it too just yet, needs tweaking as it's not adding members to the object in the second half of the script. Here's what I have so far: gpupdate.ps1
tri_94 Posted March 11, 2019 Author Posted March 11, 2019 Thanks it looks like its nearly there to me.
HPlum78 Posted March 11, 2019 Posted March 11, 2019 (edited) foreach($computer in $allComputers.Where{$_.Online -eq $True}){ #for each online computer try{ Invoke-GPUpdate -Computer $Computer.Name -RandomDelayInMinutes 0 -ErrorAction Stop | Out-Null $computer | add-member –membertype NoteProperty –name GPUpdate –value "Successful" -PassThru #invoke gpupdate on remote computer } catch{ $computer | add-member –membertype NoteProperty –name GPUpdate –value "Failed" -PassThru #add a member to object to store GP Update failed message } } } $allComputers Just took away the need for the if statement that you have doing the error trapping as try catch is what i would say to use as that's the default error trapping built in for you. Just need to be careful when you start using -erroraction as you may take the error off the pipe and make your try/ catch blocks not work as expected. Edited March 11, 2019 by HPlum78
HPlum78 Posted March 11, 2019 Posted March 11, 2019 (edited) so the code looks like this:- [system.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null $OU = [Microsoft.VisualBasic.Interaction]::InputBox($Inputbox, "Active Directory", "$OU") $Inputbox = "Please enter required OU" $allComputers = Get-ADComputer -Filter * -SearchBase "$OU" | Select-Object Name Add-Type -AssemblyName PresentationCore,PresentationFramework $ButtonType = [system.Windows.MessageBoxButton]::YesNo $MessageIcon = [system.Windows.MessageBoxImage]::Question $MessageBody = "Would you like to force a Group Policy update to this OU ?" $Result = [system.Windows.MessageBox]::Show($MessageBody,$MessageTitle,$ButtonType,$MessageIcon) If ($Result -eq 'Yes'){ #If user answers yes: foreach($computer in $allComputers){ #for each computer found: $computer | add-member –membertype NoteProperty –name Online –value (Test-Connection -ComputerName $computer.Name -Quiet -Count 1) #add a member to object to store if the computer online (True/False) } foreach($computer in $allComputers.Where{$_.Online -eq $True}){ #for each online computer try{ Invoke-GPUpdate -Computer $Computer.Name -RandomDelayInMinutes 0 -ErrorAction Stop | Out-Null $computer | add-member –membertype NoteProperty –name GPUpdate –value "Successful" -PassThru #invoke gpupdate on remote computer } catch{ $computer | add-member –membertype NoteProperty –name GPUpdate –value "Failed" -PassThru #add a member to object to store GP Update Failed message } } } $allComputers Oh I took the -force off the invoke-gpupdate line as well, if i was approaching this with PS i would look at putting in some checks around the user inputs (check for nulls and the like) also maybe worth doing a count on the number of computers and limiting the max number that the script will run against and the like. Edited March 11, 2019 by HPlum78 1
ThomL Posted March 11, 2019 Posted March 11, 2019 The try/catch is a much better way - the error control/trigger system I had in place is silly when there are built in mechanism - I totally agree. As far as checking user input,computer limiting, force/no force; ideally this would be a function and we could use parameters to set all this stuff and validate it etc. This is the latest version from my tweaking to use the try/catch and to record the correct errors in the array: gpupdate.ps1 From my testing this works as expected so now it's up to OP to refine and make a function, validation etc. I give up 1
MartinRouterKing Posted March 11, 2019 Posted March 11, 2019 This script would really come in handy. However when testing I get the below!
HPlum78 Posted March 11, 2019 Posted March 11, 2019 (edited) Replace the.Where with a |? {$_.online -eq $true} I think... Could be wrong but have not got PS handy and it's late! It's a version issue and we should have declared the version required to run. Edited March 11, 2019 by HPlum78 2
ThomL Posted March 11, 2019 Posted March 11, 2019 Replace the.Where with a |? {$_.online -eq $true} I think... Could be wrong but have not got PS handy and it's late! It's a version issue and we should have declared the version required to run. I second this, update PowerShell. 2
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now