Could use some help with learning Powershell

A little background;

I migrated our Exchange On Prem to Office 365 last year and had to learn powershell to administer it.

Since then I’ve gotten into using it to perform numerous tasks and somewhat understand it, however more advanced things like creating an array, or understanding piping, etc., leave me a bit baffled.

Ultimately what I’m trying to do is fully automate our VIRTUAL server patching and rebooting, along with verifying services set to ‘auto’ are actually started, and if not, start them from a single console.

Down the road, I want this to be a scheduled task that does the following:

Starting at 6pm the night before the scheduled reboots, tell each server to install the patches that are pushed from SCCM. Preferably this would be staggered, so that not all of the servers are hitting the SCCM server for their patch at the same time, but I have no idea how to do that.

I have all of the servers in a .csv file and would prefer to keep it this way so going forward, when adding or removing a server, there is very little maintenance to do to make the script continue to work.

Then, to wait until exactly 6am, and have it start rebooting servers, in a particular order (which could be achieved by the order they are listed in the CSV file), staggering the reboot initiation by 30 seconds between servers, so they’re not all hitting the VMware hosts at the exact same time.

Once the reboots are completed, I’d like to have a way to go through each of the servers that were bounced, and verify that any service set to auto is started, and if not, have it remotely started, with a report written.

Here’s the truth, most of what I have working so far (patching is one script, reboots are another, and I’m just running them manually for testing purposes), is stuff someone else wrote, so I’d like to learn how to do this stuff, but finding time is always a challenge.

Here’s what I have so far:

Patching:

# Determine script location $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path $log = "$ScriptDir\InstallUpdates.log" $date = Get-Date -Format "dd-MM-yyyy hh:mm:ss" # Get list of clients from notepad "--------------------- Script executed on $date (DD-MM-YYYY hh:mm:ss) ---------------------" + "`r`n" | Out-File $log -append #ForEach ($system in Get-Content $ScriptDir"\Chrisclients.txt") ForEach ($system in Import-CSV "H:\PathToCSVFile\ServersToReboot.csv") { $wmicheck=$null $wmicheck =Get-WmiObject -ComputerName $system -namespace root\cimv2 -Class Win32_BIOS -ErrorAction SilentlyContinue if ($wmicheck) { # Get list of all instances of CCM_SoftwareUpdate from root\CCM\ClientSDK for missing updates https://msdn.microsoft.com/en-us/library/jj155450.aspx?f=255&MSPPError=-2147217396 $TargetedUpdates= Get-WmiObject -ComputerName $system -Namespace root\CCM\ClientSDK -Class CCM_SoftwareUpdate -Filter ComplianceState=0 $approvedUpdates= ($TargetedUpdates |Measure-Object).count $pendingpatches=($TargetedUpdates |Where-Object {$TargetedUpdates.EvaluationState -ne 8} |Measure-Object).count $rebootpending=($TargetedUpdates |Where-Object {$TargetedUpdates.EvaluationState -eq 8} |Measure-Object).count if ($pendingpatches -gt 0) { try { $MissingUpdatesReformatted = @($TargetedUpdates | ForEach-Object {if($_.ComplianceState -eq 0){[WMI]$_.__PATH}}) # The following is the invoke of the CCM_SoftwareUpdatesManager.InstallUpdates with our found updates $InstallReturn = Invoke-WmiMethod -ComputerName $system -Class CCM_SoftwareUpdatesManager -Name InstallUpdates -ArgumentList (,$MissingUpdatesReformatted) -Namespace root\ccm\clientsdk "$system,Targeted Patches :$approvedUpdates,Pending patches:$pendingpatches,Reboot Pending patches :$rebootpending,initiated $pendingpatches patches for install" | Out-File $log -append } catch {"$System,pending patches - $pendingpatches but unable to install them ,please check Further" | Out-File $log -append } } else {"$system,Targeted Patches :$approvedUpdates,Pending patches:$pendingpatches,Reboot Pending patches :$rebootpending,Compliant" | Out-File $log -append } } else {"$system,Unable to connect to remote system ,please check further" | Out-File $log -append } }
Rebooting:

 

$header = "server" $servers = import-csv "H:\PathToCSVFile\ServersToReboot.csv" -header $header

foreach($i in $servers) {
Write-Host “Attempting to reboot:” $i.server “…”

$serverObj = gwmi Win32_operatingsystem -computer $i.server

$status = $serverObj.reboot()

if ($status.ReturnValue = “0”) {
Write-Host “Reboot successful.”
Write-Host “Waiting 15 seconds”
Start-Sleep -s 15
Write-Host “Starting Next Reboot”
} else {
Write-Host “Reboot failed. Check permissions.”
}
}


 

The reboot script works, for the most part, but once the last server is finished, it does make me wait 15 seconds before terminating, but it does work as expected.

 

I have scoured the web, and ended up here by my searches on a powershell to check on services on those servers, and to restart them if needed, but the discussion seems to fall off, or I got lost and didn’t understand.

Aside from reading a powershell book or taking another class, does anybody have any recommendations on how to accomplish this?

A book is always good :slight_smile:
Don Jones, the president of this site has quite a few books about powershell on e.g. Amazon.

If you don’t want to start with a book I would recommend to go to MVA (Microsoft Virtual Academy) and look at the two tracks with Jason Helmick and Jeffrey Snover.

  1. Getting started with Microsoft Powershell
  2. Advanced Tools & Scripting with PowerShell 3.0 Jump Start

I would recommend to look at these no matter what since they are good, not too complicated to follow and some quirky humour mixed into it :slight_smile:
If you go through both tracks you would understand the code that you posted, except maybe the WMI specific classes used.
But that shouldn’t be to hard to catch up on afterwards.

And the MVA courses are free.

I have two recommendations in general. I haven’t time to go through all of that right now, but I’m sure someone will drop by shortly enough :slight_smile:

  1. Stick around the PS communities -- there's this forum, a PowerShell subreddit, and a PS Slack or Discord (both of which are linked on the subreddit sidebar)
  2. Don't be afraid to ask questions.
I'm also working on some koans for PowerShell, if you learn better by doing & applying rather than just reading. :)

[quote quote=120580]A book is always good 🙂

Don Jones, the president of this site has quite a few books about powershell on e.g. Amazon.

If you don’t want to start with a book I would recommend to go to MVA (Microsoft Virtual Academy) and look at the two tracks with Jason Helmick and Jeffrey Snover.

  1. Getting started with Microsoft Powershell

  2. Advanced Tools & Scripting with PowerShell 3.0 Jump Start

I would recommend to look at these no matter what since they are good, not too complicated to follow and some quirky humour mixed into it 🙂

If you go through both tracks you would understand the code that you posted, except maybe the WMI specific classes used.

But that shouldn’t be to hard to catch up on afterwards.

And the MVA courses are free.

[/quote]

Excellent. I will check out those courses. Thank you for the info.

[quote quote=120582]I have two recommendations in general. I haven’t time to go through all of that right now, but I’m sure someone will drop by shortly enough 🙂

  1. Stick around the PS communities — there's this forum, a PowerShell subreddit, and a PS Slack or Discord (both of which are linked on the subreddit sidebar)
  2. Don't be afraid to ask questions.
I'm also working on some koans for PowerShell, if you learn better by doing & applying rather than just reading. 🙂

[/quote]

I’d love to really learn this stuff, so I hope to be an active member. Thanks for the tips, and I’ll check out your KOANS as I don’t know what they are.

If you want end to end I would highly recommend Don Jones’ CBTnuggets course. Goes from Opening Powershell through to nearly everything you would need to know. It is PS 2,3 and 4 nearly all of this carries forwards to 5 and 5.1

https://www.cbtnuggets.com/blog/2014/03/new-windows-powershell-v2-v3-v4-ultimate-training/

This is the moster list of awesome vids

  1. Course Introduction and Lab Setup
  2. Windows PowerShell Orientation and Requirements
  3. Finding and Discovering Commands
  4. Interpreting Command Help
  5. Running Commands
  6. Working with PSProviders and PSDrives
  7. Variables, Strings, Hashtables, and Core Operators
  8. Regular Expression Basics
  9. Running External Commands: Tips and tricks
  10. Learning the Pipeline: Exporting and converting data
  11. Understanding Objects in PowerShell
  12. Core Commands: Selecting, sorting, measuring, and more
  13. How the PowerShell Pipeline Works
  14. Formatting Command Output
  15. Comparison Operators and Filtering
  16. Advanced Operators
  17. Setting Default Values for Command Parameters
  18. Enumerating Objects in the Pipeline
  19. Soup to Nuts: Completing a new task
  20. Lab A: PowerShell core review
  21. PowerShell Remoting Basics
  22. Persistent Remoting: PSSessions
  23. Implicit Remoting: Using commands on another computer
  24. Advanced Remoting: Passing data and working with output
  25. Advanced Remoting: Crossing domain boundaries
  26. Advanced Remoting: Custom session configurations
  27. Web Remoting: PowerShell web access
  28. Lab B: PowerShell remoting review
  29. WMI and CIM: WMI, docs, and the repository
  30. WMI and CIM: Using WMI to command query qata
  31. WMI and CIM: Using CIM command to query data, part 2
  32. WMI and CIM: Filtering and WMI query language
  33. WMI and CIM: Associations
  34. WMI and CIM: Working with CIM sessions
  35. WMI and CIM: Executing instance methods
  36. Lab C: WMI and CIM review
  37. Background Job Basics: Local, WMI, and Remoting jobs
  38. Scheduled Background Jobs
  39. Lab D: Jobs review
  40. PowerShell Script Security
  41. Prompting for Input, Producing Output
  42. Creating Basic Parameterized Scripts
  43. PowerShell Scripting: Logical constructs
  44. PowerShell Scripting: Looping constructs
  45. PowerShell Scripting: Basic functions, filters, and pipeline functions
  46. PowerShell Scripting: Best practices
  47. PowerShell Scripting: From command to script to function to module
  48. PowerShell Scripting: Scope
  49. PowerShell Scripting: Combining data from multiple sources
  50. Lab E: PowerShell scripting review
  51. Advanced Functions: Adding Help
  52. Advanced Functions: Parameter Attributes
  53. Advanced Functions: Pipeline Input
  54. Advanced Functions: Parameter Sets
  55. Lab F: Advanced Functions Review
  56. Creating Private Utility Functions and Preference Variables
  57. Adding Error Capturing and Handling to a Function
  58. Advanced Error Handling
  59. Error Handling the Old Way: Trap
  60. Debugging Techniques
  61. Creating Custom Formatting Views
  62. Creating Custom Type Extensions
  63. Working with SQL Server (and other) Databases
  64. Working with XML Data Files
  65. Supporting –WhatIf and –Confirm in Functions
  66. Troubleshooting and Tracing the Pipeline
  67. Using Object Hierarchies for Complex Output
  68. Creating a Proxy Function
  69. Lab G: Advanced Scripting Review
  70. From the Field: Enhanced HTML Reporting
  71. From the Field: Trend Analysis Reporting
  72. From the Field: Scraping HTML Pages
  73. Introduction to PowerShell Workflow
  74. Desired State Configuration: The Basics
  75. Desired State Configuration: Configuration Scripts and Pull Servers
  76. Desired State Configuration: Writing Resources
  77. Controller Scripts: Automating Business Processes
  78. Controller Scripts: A Menu of Tools
  79. Creating a GUI Tool: The GUI
  80. Creating a GUI Tool: The Code
  81. Creating a GUI Tool: The Output
  82. Creating a GUI Tool: Using Data Tables
  83. Lab H: Automating a Business Process
  84. Globalizing a Function or Script
  85. Discovering and Using COM Objects
  86. Discovering and Using .NET Classes and Instances
  87. Using Type Accelerators
  88. The Big Gotchas in PowerShell
  89. Fun With Profiles
  90. Random Tips and Tricks

If you look on the forums for questions that interest you then search the internet for ways to solve the questions I find is a good way to learn, as this way you will learn things for solutions that you may of not thought of. Also I agree the MVA courses are good as well as PowerShell in a month of lunches