Jump to content

Script to export OU and then check if online and then gp update


Recommended Posts

Posted

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

 

 

 

}

 

 

}

Posted
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.
Posted
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 :)
Posted

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

Posted
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
Posted (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 by HPlum78
Posted (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 by HPlum78
  • Thanks 1
Posted

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 :cool:

  • Thanks 1
Posted (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 by HPlum78
  • Thanks 2
Posted
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.

  • Thanks 2

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 account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...