Skip to content

Commit 61103bd

Browse files
Improves documentation
1 parent 84d7d50 commit 61103bd

7 files changed

Lines changed: 175 additions & 99 deletions

README.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# AutomaticMaintenance
2+
23
The purpose of the module is to orchestrate Windows update installation and related tasks on a bunch of network hosts.
34
The module implements the following workflow:
5+
46
1. Checks if maintenance is needed for a computer.
57
2. Removes all workload from that host.
68
3. Performs maintenance tasks (updates installation).
@@ -16,7 +18,9 @@ The main function you need from this module is [**Invoke-InfrastructureMaintenan
1618
Under the hood, **Invoke-InfrastructureMaintenance** uses another function to actually perform maintenance on each host — [**Invoke-ComputerMaintenance**](docs/Invoke-ComputerMaintenance.md). If you want to use an external orchestration/configuration management system (Ansible, Puppet etc.), configure it to execute **Invoke-ComputerMaintenance**, not **Invoke-InfrastructureMaintenance**.
1719

1820
## Update detection and installation
21+
1922
**Invoke-ComputerMaintenance** uses the standard Windows Update API to detect and install updates. That means that to make updates available for a host, you have to make them available at WSUS or use direct connection to Microsoft Update. But you can exclude some updates from installation/detection:
23+
2024
* Use the `UpdateInstallFilter` configuration attribute (or the `$ModuleWideInstallUpdateDefaultFilterString` module configuration variable) to specify filter for updates installation.
2125
* Use the `UpdateCheckFilter` configuration attribute (or the `$ModuleWideCheckUpdateDefaultFilterString` module configuration variable) to specify filter for updates detection.
2226

@@ -25,7 +29,9 @@ If the detection process (**Test-WindowsUpdateNeeded**) finds available updates,
2529
There's no built-in way to install a specific update, but it is possible by leveraging plug-ins (see below), since you can execute custom commands and scripts there.
2630

2731
## Host types
32+
2833
While the module can potentially support machines with various type of workloads, currently there are only three supported types:
34+
2935
* **HV-SCVMM** - for stand-alone hypervisors (yes, *not* fail-over clusters) managed by SCVMM. Workload movement is provided by the [SCVMReliableMigration](https://github.com/FozzyHosting/SCVMReliableMigration) module.
3036
* **HV-Vanilla** - for stand-alone hypervisors. Workload movement is provided by the [HVVMReliableMigration](https://github.com/FozzyHosting/HVVMReliableMigration) module.
3137
* **Generic** - hosts of this type do not need any specific actions to move workload and the only purpose to perform maintenance on them, using this module, is to prevent a situation when all hosts supporting a service are down at the same time.
@@ -35,42 +41,53 @@ Note, that failover cluster support was never the goal while developing the modu
3541
The module does not specify type-specific modules as requirements, since you might use it for one type of hosts but not for another. Just bear in mind that you still will need those modules to service particular types of hosts.
3642

3743
## Configuration
44+
3845
The module's main configuration file `AutomaticMaintenance-Hosts.json` contains a list of hosts to process. Read more about the configuration [here](docs-additional/Configuration.md).
3946

4047
## Plug-ins
48+
4149
You can run your custom scripts in between of the maintenance steps specified above. You can even pass variables from one of them to another!
4250
Read more about this awesome concept [here](docs-additional/Plug-ins.md).
4351

4452
## Error processing
53+
4554
All the module's functions but **Invoke-InfrastructureMaintenance** process errors by raising a terminating exception. **Invoke-InfrastructureMaintenance** writes an error message and a stack trace into an error log (see below).
4655

4756
By default, if you run **Invoke-InfrastructureMaintenance** and there is an error log from a previous crash, it will stop. You can configure this behaviour with the `$ModuleWideFailOnPreviousFailure` variable.
4857

4958
## Exported functions
59+
5060
* [Get-ComputerMaintenanceConfiguration](docs/Get-ComputerMaintenanceConfiguration.md)
5161
* [Invoke-ComputerMaintenance](docs/Invoke-ComputerMaintenance.md)
5262
* [Invoke-InfrastructureMaintenance](docs/Invoke-InfrastructureMaintenance.md)
5363

5464
## Log files
65+
5566
There are three types log files:
67+
5668
* An error log file (`AutomaticMaintenance-Error.log`).
5769
* Debug log files: Invoke-ComputerMaintenance function will write all executed commands into separate log-files - one per host (`AutomaticMaintenance-<Host Name>-<Current Date>.log`).
5870
* Maintenance track log file. Its main purpose is to let you keep a track of when which host has been maintained (`AutomaticMaintenance-HostMaintenanceLog.log`).
5971

6072
## Dependencies
73+
6174
The module depends on the following modules:
75+
6276
* [PendingReboot](https://github.com/bcwilhite/PendingReboot) - To detect if a reboot is required after updates installation.
6377
* [ResourceLocker](https://github.com/FozzyHosting/ResourceLocker) - To let other automation know that the host is about to reboot. Also it is used to prevent reboots while the host is used by some other functions/scripts.
6478
* [SimpleTextLogger](https://github.com/FozzyHosting/SimpleTextLogger) - To log actions and errors.
6579
* [SplitOutput](https://github.com/exchange12rocks/SplitOutput) - To log debug output.
6680

6781
### HV-SCVMM
82+
6883
For hosts of the `HV-SCVMM` type, the module uses [SCVMReliableMigration](https://github.com/FozzyHosting/SCVMReliableMigration) to migrate workload between them.
6984

7085
### HV-Vanilla
86+
7187
For hosts of the `HV-Vanilla` type, the module uses [HVVMReliableMigration](https://github.com/FozzyHosting/HVVMReliableMigration) to migrate workload.
7288

7389
## Module-wide variables
90+
7491
There are several variables defined in the .psm1-file, which are used by the module's functions as default values for parameters:
7592

7693
* `[string]$LogFileFolderPath` - Specifies the path to a folder where debug and error log files will be placed.
@@ -105,22 +122,31 @@ There are several variables defined in the .psm1-file, which are used by the mod
105122
* `[string]$ModuleWideInstallUpdateTaskDescription` - The description of a Task Scheduler task which executes code to find and install updates.
106123
* `[string]$ModuleWideCheckUpdateDefaultFilterString` - A filter which is used to detect new updates. Used if an `UpdateCheckFilter` attribute is not defined in host's configuration.
107124
* `[string]$ModuleWideInstallUpdateDefaultFilterString` - A filter which is used during updates installation. Used if an `UpdateInstallFilter` attribute is not defined in host's configuration.
108-
* `[string]$ModuleWideUpdateSearchCriteria` - Criteria for the IUpdateSearcher::Search method (https://docs.microsoft.com/en-us/windows/desktop/api/wuapi/nf-wuapi-iupdatesearcher-search)
125+
* `[string]$ModuleWideUpdateSearchCriteria` - Criteria for the IUpdateSearcher::Search method (<https://docs.microsoft.com/en-us/windows/desktop/api/wuapi/nf-wuapi-iupdatesearcher-search>)
109126

110127
* `[bool]$ModuleWideHVVanillaPutInASubfolder` - When set to `$true` (default), places vanilla Hyper-V virtual machines in subfolders, named as VMs themselves, therefore mimicking SCVMM behavior. Requires access to WinRM on the target computer and access to the Win32_Directory WMI class.
111128

112129
## Loading variables from an external source
130+
113131
All module-wide variables can be redefined with a `Config.ps1` file, located in the module's root folder. Just put variable definitions in there as you would do with any other PowerShell script. You may find an example of a config file `Config-Example.ps1` in the module's root folder.
114132

115133
## Limitations
134+
116135
* Currently, all hosts should be available by all of the following protocols: RPC, WinRM, SMB.
117136
* %SystemRoot%\system32\dllhost.exe should be able to accept network connections to RPC Dynamic ports not only as a service, but as an ordinary process as well.
137+
138+
* ```powershell
139+
New-NetFirewallRule -DisplayName 'TEST' -Action Allow -Direction Inbound -Enabled True -LocalPort RPC -PolicyStore PersistentStore -Program '%SystemRoot%\system32\dllhost.exe' -Protocol TCP
140+
```
141+
118142
* User, which runs Invoke-ComputerMaintenance or Invoke-InfrastructureMaintenance, should be a local administrator at the hosts.
119143
* The module has a tight dependency on the ResourceLocker module - currently it's improssible to use it w/o that module.
120144
* The module is single-treaded, no parallelization support yet.
121145
122146
## What's with all the Write-Debug calls?
123-
https://exchange12rocks.org/2018/11/20/how-do-you-debug-your-powershell-code/
147+
148+
<https://exchange12rocks.org/2018/11/20/how-do-you-debug-your-powershell-code/>
124149
125150
## Related links
126-
https://github.com/Sorrowfulgod/UpdateService
151+
152+
<https://github.com/Sorrowfulgod/UpdateService>

docs-additional/Configuration.md

Lines changed: 79 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,42 @@
11
# Configuration
2+
23
The module's configuration consists of two files located in the module's folder: `AutomaticMaintenance-Hosts.json` and `AutomaticMaintenance-Templates.json`
34

45
## AutomaticMaintenance-Hosts.json
6+
57
The main file where you should put all hosts which you want to maintain.
68

79
Please take a look at [AutomaticMaintenance-Hosts-Example.json](../AutomaticMaintenance-Hosts-Example.json) for examples on how to build this file.
810

911
## AutomaticMaintenance-Templates.json
12+
1013
This file allows you to build your configuration more efficiently by introducing a concept of templates
1114
You don't HAVE to use templates: if you don't like them, just describe each host separately in a hosts configuration file.
1215

1316
Please take a look at [AutomaticMaintenance-Templates-Example.json](../AutomaticMaintenance-Templates-Example.json) for examples on how to build this file.
1417

1518
Each template must have at least two attributes:
19+
1620
* Name - The name of a template. Should be unique.
1721
* Properties - An array of properties to apply to hosts, which use this template.
1822

1923
### Template including
24+
2025
You can include templates into each other. Use an attribute `Include` for that.
2126
The `Include` attribute defines a collection of objects. Each of those objects must have two following attributes:
27+
2228
* Name - The name of a template from which the current template should inherit host properties.
2329
* Priority - Used to resolve conflicts if you include several templates into one.
2430

2531
## Attributes
32+
2633
* Name - The name of a host where you want to install updates automatically. Should be unique.
2734
* Type - A type of a host. Currently, the acceptable values are `HV-SCVMM`, `HV-Vanilla`, `Generic`.
2835
* UpdateInstallFilter - A filter which is used to filter out unneeded updates, like preview versions etc.
2936
* Disabled - Settings this attribute to `True` allows you to temporary disable processing of this particular host. Useful when you need to perform some manual maintenance.
3037

3138
The following set of attributes describes plug-ins:
39+
3240
* PreClearCommands
3341
* PostClearCommands
3442
* PreRestoreCommands
@@ -39,110 +47,111 @@ The following set of attributes describes plug-ins:
3947
Each attribute is usually a name of a PowerShell script, located in the `$ModuleWideScriptBlocksFolderPath` folder in the module's folder. See more about these commands [here](Plug-ins.md)
4048

4149
### Workload-specific attributes
50+
4251
#### HV-SCVMM
52+
4353
* VMMServerName - A name of a VMM server which manages the current host.
4454
* Workload - Defines a container with workload objects which describe how to migrate virtual machines before host maintenance.
4555

4656
Workload objects have the following attributes:
57+
4758
* Path - Path where VM's configuration is located.
4859
* DestinationName - Destination host's name where to move virtual machines.
4960
* DestinationPath - Local path on the destination host.
5061
* Filter - Defines a filter which will be used to pick VMs from the source host. For example, if you wish for some VMs not to mirate, but stay at the source host during maintenance, you can filter them out here.
5162

5263
#### HV-Vanilla
64+
5365
Generally, the same as `HV-SCVMM`, just without the `VMMServerName` attribute.
66+
5467
* PutInASubfolder - When set to `true`, places vanilla Hyper-V virtual machines in subfolders, named as VMs themselves, therefore mimicking SCVMM behavior. Can be set on both the host and workload levels. When defined on the workload level, rewrites the value defined on the host level. If the attribute is not defined in host configuration, the default value (`$ModuleWideHVVanillaPutInASubfolder`) is used.
5568

5669
## Configuration testing
70+
5771
The module exposes the **Get-ComputerMaintenanceConfiguration** function to retrieve a resulting configuration for a host. This function is used by the module itself to build host's configuration. Use it to test your configuration files before deploying them to production.
5872

5973
To review the resulting configuration from the `AutomaticMaintenance-Hosts-Example.json` and `AutomaticMaintenance-Templates-Example.json` files, remove example suffixes from their names and load the module into a current PowerShell session. Then run **Get-ComputerMaintenanceConfiguration**, specifying different computer names. Here's what you should get (the output here is sorted to improve readability):
6074

6175
### SRV01
62-
```
63-
Name : SRV01
64-
Template : Example-Template
65-
PreClearCommands : Example-PreClear.ps1
66-
PostClearCommands : Example-PostClear.ps1
67-
TestCommands : Example-Test.ps1
68-
PreRestoreCommands : Example-PreRestore.ps1
69-
PostRestoreCommands : Example-PostRestore.ps1
70-
FinallyCommands : Example-Finally.ps1
71-
UpdateInstallFilter : $_.Title -notlike '*Preview*' -and $_.Title -notlike '*Silverlight*' -and $_.Title -notlike
72-
'*Security Only*'
73-
```
76+
77+
Name : SRV01
78+
Template : Example-Template
79+
PreClearCommands : Example-PreClear.ps1
80+
PostClearCommands : Example-PostClear.ps1
81+
TestCommands : Example-Test.ps1
82+
PreRestoreCommands : Example-PreRestore.ps1
83+
PostRestoreCommands : Example-PostRestore.ps1
84+
FinallyCommands : Example-Finally.ps1
85+
UpdateInstallFilter : $_.Title -notlike '*Preview*' -and $_.Title -notlike '*Silverlight*' -and $_.Title -notlike
86+
'*Security Only*'
7487

7588
This is a basic example: a host has only one template (`Example-Template`).
7689

7790
### SRV02
78-
```
79-
Name : SRV02
80-
Template : Example-Template
81-
PreClearCommands : Example-PreClear.ps1
82-
PostClearCommands : Example-PostClear.ps1
83-
TestCommands : Example-Test.ps1
84-
PreRestoreCommands : Example-PreRestore.ps1
85-
PostRestoreCommands : Example-PostRestore.ps1
86-
FinallyCommands : Example-Finally.ps1
87-
UpdateInstallFilter : $_.Title -notlike '*Preview*' -and $_.Title -notlike '*Silverlight*' -and $_.Title -notlike
88-
'*Security Only*'
89-
MyCustomAttribute : CustomValue2
90-
```
91+
92+
Name : SRV02
93+
Template : Example-Template
94+
PreClearCommands : Example-PreClear.ps1
95+
PostClearCommands : Example-PostClear.ps1
96+
TestCommands : Example-Test.ps1
97+
PreRestoreCommands : Example-PreRestore.ps1
98+
PostRestoreCommands : Example-PostRestore.ps1
99+
FinallyCommands : Example-Finally.ps1
100+
UpdateInstallFilter : $_.Title -notlike '*Preview*' -and $_.Title -notlike '*Silverlight*' -and $_.Title -notlike
101+
'*Security Only*'
102+
MyCustomAttribute : CustomValue2
91103

92104
SRV02 also uses Example-Template, but on the host level, there's a new attribute defined: `MyCustomAttribute`. The attribute neatly merged with the resulting configuration.
93105

94106
### SRV03
95-
```
96-
Name : SRV03
97-
Template : Example-Template2
98-
Type : HV-SCVMM
99-
PreClearCommands : Example-PreClear.ps1
100-
PostClearCommands : Example-PostClear.ps1
101-
TestCommands : Example-Test.ps1
102-
PreRestoreCommands : Example-PreRestore.ps1
103-
PostRestoreCommands : Example-PostRestore.ps1
104-
FinallyCommands : Example-Finally.ps1
105-
UpdateInstallFilter : $_.Title -notlike '*Preview*' -and $_.Title -notlike '*Silverlight*' -and $_.Title -notlike
106-
'*Security Only*'
107-
VMMServerName : SRVVMM01
108-
Workload : {@{Path=C:\VMs; DestinationName=SRV05; DestinationPath=D:\VMs; Filter=$_.Name -notlike
109-
'*-DontMove'}, @{Path=E:\VMs; DestinationName=SRV05; DestinationPath=E:\VMs; Filter=$_.Name
110-
-notlike '*-DontMove'}}
111-
```
107+
108+
Name : SRV03
109+
Template : Example-Template2
110+
Type : HV-SCVMM
111+
PreClearCommands : Example-PreClear.ps1
112+
PostClearCommands : Example-PostClear.ps1
113+
TestCommands : Example-Test.ps1
114+
PreRestoreCommands : Example-PreRestore.ps1
115+
PostRestoreCommands : Example-PostRestore.ps1
116+
FinallyCommands : Example-Finally.ps1
117+
UpdateInstallFilter : $_.Title -notlike '*Preview*' -and $_.Title -notlike '*Silverlight*' -and $_.Title -notlike
118+
'*Security Only*'
119+
VMMServerName : SRVVMM01
120+
Workload : {@{Path=C:\VMs; DestinationName=SRV05; DestinationPath=D:\VMs; Filter=$_.Name -notlike
121+
'*-DontMove'}, @{Path=E:\VMs; DestinationName=SRV05; DestinationPath=E:\VMs; Filter=$_.Name
122+
-notlike '*-DontMove'}}
112123

113124
SRV03 is a stand-alone Hyper-V host, that's why it uses `Example-Template2`, which describes how to maintain Hyper-V hosts in this example infrastructure.
114125
Note, that `Example-Template2` does not have plug-ins defined, but the template itself inherits properties from `Example-Template`, that's why we see all those attributes in the configuration. This also gives us `UpdateInstallFilter`.
115126

116127
### SRV04
117-
```
118-
Name : SRV04
119-
Template : Example-Template2
120-
Type : HV-SCVMM
121-
PreClearCommands : Example-PreClear.ps1
122-
PostClearCommands : Example-PostClear.ps1
123-
TestCommands : Example-Test.ps1
124-
PreRestoreCommands : Example-PreRestore.ps1
125-
PostRestoreCommands :
126-
FinallyCommands : Example-Finally.ps1
127-
UpdateInstallFilter : $_.Title -notlike '*Preview*' -and $_.Title -notlike '*Silverlight*' -and $_.Title -notlike
128-
'*Security Only*'
129-
VMMServerName : SRVVMM01
130-
MyCustomAttribute : CustomValue1
131-
Workload : {@{Path=D:\VMs; DestinationName=SRV05; DestinationPath=E:\VMs; Filter=$_.Name -notlike
132-
'*-DontMove'}}
133-
```
128+
129+
Name : SRV04
130+
Template : Example-Template2
131+
Type : HV-SCVMM
132+
PreClearCommands : Example-PreClear.ps1
133+
PostClearCommands : Example-PostClear.ps1
134+
TestCommands : Example-Test.ps1
135+
PreRestoreCommands : Example-PreRestore.ps1
136+
PostRestoreCommands :
137+
FinallyCommands : Example-Finally.ps1
138+
UpdateInstallFilter : $_.Title -notlike '*Preview*' -and $_.Title -notlike '*Silverlight*' -and $_.Title -notlike
139+
'*Security Only*'
140+
VMMServerName : SRVVMM01
141+
MyCustomAttribute : CustomValue1
142+
Workload : {@{Path=D:\VMs; DestinationName=SRV05; DestinationPath=E:\VMs; Filter=$_.Name -notlike
143+
'*-DontMove'}}
134144

135145
Similar to SRV03, but has `MyCustomAttribute` defined at the host level. Also note that the `PostRestoreCommands` property is empty because at the host level it is also empty — you can redefine attributes at any level. The `Workload` property is redefined as well.
136146

137147
### SRV05
138-
```
139-
Name : SRV05
140-
Type : HV-SCVMM
141-
VMMServerName : SRVVMM01
142-
MyCustomAttribute : CustomValue1
143-
Workload : {@{Path=D:\VMs; DestinationName=SRV03; DestinationPath=C:\VMs; Filter=$_.Name -notlike
144-
'*-DontMove'}, @{Path=E:\VMs; DestinationName=SRV03; DestinationPath=E:\VMs; Filter=$_.Name
145-
-notlike '*-DontMove'}}
146-
```
147-
148-
This host does not use any templates: all its attributes are defined at the host level — that's why it's configuration lacks plug-ins etc.
148+
149+
Name : SRV05
150+
Type : HV-SCVMM
151+
VMMServerName : SRVVMM01
152+
MyCustomAttribute : CustomValue1
153+
Workload : {@{Path=D:\VMs; DestinationName=SRV03; DestinationPath=C:\VMs; Filter=$_.Name -notlike
154+
'*-DontMove'}, @{Path=E:\VMs; DestinationName=SRV03; DestinationPath=E:\VMs; Filter=$_.Name
155+
-notlike '*-DontMove'}}
156+
157+
This host does not use any templates: all its attributes are defined at the host level — that's why it's configuration lacks plug-ins etc.

0 commit comments

Comments
 (0)