├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .markdownlint.json ├── LICENSE ├── PoShGroupPolicy ├── PoShGroupPolicy.psd1 ├── PoShGroupPolicy.psm1 ├── Private │ ├── Get-GPKnownFolderId.ps1 │ └── Get-RsGpoReport.ps1 ├── Public │ └── Get-GPSetting.ps1 ├── Scripts │ └── .gitignore ├── TypeData │ ├── PoShGroupPolicy.Format.ps1xml │ └── PoShGroupPolicy.Types.ps1xml └── en-US │ └── about_PoShGroupPolicy.help.txt ├── README.md ├── ReleaseNotes.md ├── docs ├── CHANGELOG.md ├── README.md └── requirements.txt └── mkdocs.yml /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve the module 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: thedavecarroll 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **PowerShell Environment (please complete the following information):** 23 | - OS: [e.g. Windows 10, Ubuntu 18.04] 24 | - Edition [e.g. desktop,core] 25 | - Version [e.g. 5.1,6,6.1] 26 | 27 | **Additional context** 28 | Add any other context about the problem here. 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea or new feature for this module 4 | title: "[New Feature]" 5 | labels: enhancement 6 | assignees: thedavecarroll 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD006": false, 3 | "MD013": false, 4 | "MD029": false, 5 | "MD033": false 6 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Dave Carroll 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PoShGroupPolicy/PoShGroupPolicy.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module 'PSGet_PoShGroupPolicy' 3 | # 4 | # Generated by: Dave Carroll 5 | # 6 | # Generated on: 3/18/2018 7 | # 8 | 9 | @{ 10 | 11 | # Script module or binary module file associated with this manifest. 12 | RootModule = 'PoShGroupPolicy.psm1' 13 | 14 | # Version number of this module. 15 | ModuleVersion = '0.4' 16 | 17 | # Supported PSEditions 18 | # CompatiblePSEditions = @() 19 | 20 | # ID used to uniquely identify this module 21 | GUID = 'fa6fcad4-9c3f-4258-8475-bbf11060b779' 22 | 23 | # Author of this module 24 | Author = 'Dave Carroll' 25 | 26 | # Company or vendor of this module 27 | CompanyName = 'Unknown' 28 | 29 | # Copyright statement for this module 30 | Copyright = '(c) 2018 Dave Carroll. All rights reserved.' 31 | 32 | # Description of the functionality provided by this module 33 | Description = 'PowerShell module to assist with Group Policy' 34 | 35 | # Minimum version of the Windows PowerShell engine required by this module 36 | PowerShellVersion = '3.0' 37 | 38 | # Name of the Windows PowerShell host required by this module 39 | # PowerShellHostName = '' 40 | 41 | # Minimum version of the Windows PowerShell host required by this module 42 | # PowerShellHostVersion = '' 43 | 44 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 45 | # DotNetFrameworkVersion = '' 46 | 47 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 48 | # CLRVersion = '' 49 | 50 | # Processor architecture (None, X86, Amd64) required by this module 51 | # ProcessorArchitecture = '' 52 | 53 | # Modules that must be imported into the global environment prior to importing this module 54 | # RequiredModules = @('GroupPolicy') 55 | 56 | # Assemblies that must be loaded prior to importing this module 57 | # RequiredAssemblies = @() 58 | 59 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 60 | # ScriptsToProcess = @() 61 | 62 | # Type files (.ps1xml) to be loaded when importing this module 63 | # TypesToProcess = @() 64 | 65 | # Format files (.ps1xml) to be loaded when importing this module 66 | # FormatsToProcess = @('') 67 | 68 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 69 | # NestedModules = @() 70 | 71 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 72 | FunctionsToExport = 'Get-GPSetting' 73 | 74 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 75 | CmdletsToExport = @() 76 | 77 | # Variables to export from this module 78 | # VariablesToExport = @() 79 | 80 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 81 | AliasesToExport = @() 82 | 83 | # DSC resources to export from this module 84 | # DscResourcesToExport = @() 85 | 86 | # List of all modules packaged with this module 87 | # ModuleList = @() 88 | 89 | # List of all files packaged with this module 90 | FileList = 'PoShGroupPolicy.psd1', 'PoShGroupPolicy.psm1', 91 | 'en-US\about_PoShGroupPolicy.help.txt', 92 | 'Private\Get-GPKnownFolderId.ps1', 'Public\Get-GPSetting.ps1', 93 | 'TypeData\PoShGroupPolicy.Format.ps1xml' 94 | 95 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 96 | PrivateData = @{ 97 | 98 | PSData = @{ 99 | 100 | #Category of this module 101 | Category = 'Group Policy' 102 | 103 | #RequireLicenseAcceptance of this module 104 | RequireLicenseAcceptance = 'False' 105 | 106 | #IsPrerelease of this module 107 | IsPrerelease = 'True' 108 | 109 | # Tags applied to this module. These help with module discovery in online galleries. 110 | Tags = 'PoshGroupPolicy','GroupPolicy','Group-Policy','PowerShell','GPO','AzureAutomationNotSupported' 111 | 112 | # A URL to the license for this module. 113 | LicenseUri = 'https://github.com/thedavecarroll/PoShGroupPolicy/blob/master/LICENSE' 114 | 115 | # A URL to the main website for this project. 116 | ProjectUri = 'https://github.com/thedavecarroll/PoShGroupPolicy' 117 | 118 | # A URL to an icon representing this module. 119 | # IconUri = '' 120 | 121 | # ReleaseNotes of this module 122 | ReleaseNotes = '' 123 | 124 | # External dependent modules of this module 125 | ExternalModuleDependencies = 'GroupPolicy' 126 | 127 | } # End of PSData hashtable 128 | 129 | } # End of PrivateData hashtable 130 | 131 | # HelpInfo URI of this module 132 | # HelpInfoURI = '' 133 | 134 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 135 | # DefaultCommandPrefix = '' 136 | 137 | } 138 | 139 | -------------------------------------------------------------------------------- /PoShGroupPolicy/PoShGroupPolicy.psm1: -------------------------------------------------------------------------------- 1 | [CmdLetBinding()] 2 | param() 3 | 4 | #Requires -Modules GroupPolicy 5 | 6 | # dot source public and private function definition files, export publich functions 7 | try { 8 | foreach ($Scope in 'Public','Private') { 9 | Get-ChildItem "$PSScriptRoot\$Scope" -Filter *.ps1 | ForEach-Object { 10 | . $_.FullName 11 | if ($Scope -eq 'Public') { 12 | Export-ModuleMember -Function $_.BaseName -ErrorAction Stop 13 | } 14 | } 15 | } 16 | } 17 | catch { 18 | Write-Error ("{0}: {1}" -f $_.BaseName,$_.Exception.Message) 19 | exit 1 20 | } 21 | 22 | # import format and type data 23 | Try { 24 | Update-FormatData "$PSScriptRoot\TypeData\PoshGroupPolicy.Format.ps1xml" -ErrorAction Stop 25 | } 26 | catch { 27 | Write-Error ("{0}: {1}" -f 'Update-FormatData',$_.Exception.Message) 28 | exit 1 29 | } 30 | #try { 31 | #Update-TypeData "$PSScriptRoot\TypeData\PoshRSJob.Types.ps1xml" -ErrorAction Stop 32 | #} 33 | #catch {} 34 | -------------------------------------------------------------------------------- /PoShGroupPolicy/Private/Get-GPKnownFolderId.ps1: -------------------------------------------------------------------------------- 1 | function Get-GPKnownFolderId { 2 | $WebRequest = Invoke-WebRequest -Uri "https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx" 3 | $Ids = $WebRequest.AllElements | Where-Object {$_.Class -eq "mtps-table clsStd"} | Select-Object -ExpandProperty InnerText 4 | 5 | foreach ($Record in $Ids) { 6 | [PsCustomObject]@{ 7 | GUID = $Record.Split("`n")[0].Replace("GUID","").Trim() 8 | DisplayName = $Record.Split("`n")[1].Replace("Display Name","").Trim() 9 | FolderType = $Record.Split("`n")[2].Replace("Folder Type","").Trim() 10 | DefaultPath = $Record.Split("`n")[3].Replace("Default Path","").Trim() 11 | CSIDLEquivalent = $Record.Split("`n")[4].Replace("CSIDL Equivalent","").Trim() 12 | LegacyDisplayName = $Record.Split("`n")[5].Replace("Legacy Display Name","").Trim() 13 | LegacyDefaultPath = $Record.Split("`n")[6].Replace("Legacy Default Path","").Trim() 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /PoShGroupPolicy/Private/Get-RsGpoReport.ps1: -------------------------------------------------------------------------------- 1 | function Get-RsGpoReport { 2 | [CmdLetBinding()] 3 | param( 4 | [ValidateNotNullOrEmpty()] 5 | [Parameter(ValueFromPipeline)] 6 | [Microsoft.GroupPolicy.Gpo[]]$GroupPolicy, 7 | 8 | [int]$MaxThreads = 10 9 | ) 10 | 11 | begin { 12 | 13 | $Timer = [System.Diagnostics.Stopwatch]::StartNew() 14 | 15 | $WorkerPool = [System.Collections.Generic.List[Object]]::new() 16 | 17 | $RunspacePool = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1,$MaxThreads) 18 | $PowerShell = [System.Management.Automation.PowerShell]::Create() 19 | $PowerShell.RunspacePool = $RunspacePool 20 | $RunspacePool.Open() 21 | } 22 | 23 | process { 24 | 25 | foreach ($GPO in $GroupPolicy) { 26 | 27 | $Worker = [System.Management.Automation.PowerShell]::Create() 28 | $Worker.RunspacePool = $RunspacePool 29 | 30 | $ScriptBlock = { 31 | param ($GPO) 32 | $GPO.DisplayName | Write-Verbose -Verbose 33 | 34 | $ManagedThreadId = [System.Threading.Thread]::CurrentThread.ManagedThreadId 35 | 'Managed Thread Id: Beginning {0}' -f $ManagedThreadId | Write-Verbose -Verbose 36 | 37 | try { 38 | 'Generate XML Report...' | Write-Verbose -Verbose 39 | [void]$GPO.GenerateReport('xml') 40 | 'Generate XML Report...completed' | Write-Verbose -Verbose 41 | } 42 | catch { 43 | $_ 44 | } 45 | 'Managed Thread Id: Ending {0}' -f $ManagedThreadId | Write-Verbose -Verbose 46 | } 47 | 48 | [void]$Worker.AddScript($ScriptBlock).AddArgument($GPO) 49 | 50 | $Handle = $Worker.BeginInvoke() 51 | $WorkerPool.Add( 52 | [PSCustomObject]@{ 53 | Worker = $Worker 54 | Handle = $Handle 55 | } 56 | ) 57 | 58 | 'Available Runspaces in RunspacePool: {0}' -f $RunspacePool.GetAvailableRunspaces() | Write-Debug 59 | 'Remaining Jobs: {0}' -f @($WorkerPool | Where-Object { $_.Handle.iscompleted -ne 'Completed'}).Count | Write-Debug 60 | } 61 | 62 | } 63 | 64 | end { 65 | 66 | $WorkerPool | ForEach-Object { 67 | $_.Worker.EndInvoke($_.Handle) 68 | $_.Worker.Dispose() 69 | } 70 | 71 | $RunspacePool.Close() 72 | 73 | 'Elapsed Time: {0}h:{0}mm:{0}ss' -f $Timer | Write-Verbose 74 | } 75 | 76 | } -------------------------------------------------------------------------------- /PoShGroupPolicy/Public/Get-GPSetting.ps1: -------------------------------------------------------------------------------- 1 | function Get-GPSetting { 2 | <# 3 | .SYNOPSIS 4 | Get the group policy settings for specific extensions or list configured extensions. 5 | 6 | .DESCRIPTION 7 | This function will display the group policy settings of the supplied group policy 8 | objects, or will display the extensions for which the group policy contains 9 | configuration settings. 10 | 11 | It uses the GenerateReport() method of the group policy .Net object to create an 12 | XML version of the report which it then parses. 13 | 14 | Since generating XML can be time consuming, the Verbose common parameter can be 15 | specified which will provide notices to the user while it is processing. 16 | 17 | .PARAMETER GroupPolicy 18 | The group policy or array of group policies for which to return the settings. 19 | 20 | .PARAMETER Type 21 | The type of data returned. Accepted values are: 22 | 23 | ExtensionType 24 | This type of returned data will identify which group policy extensions contain 25 | configuration. This can return extension types beyond what the function can 26 | currently process. 27 | 28 | Script 29 | DriveMapSetting 30 | SecuritySetting 31 | RegistrySetting 32 | FolderRedirectionSetting 33 | 34 | .INPUTS 35 | Microsoft.GroupPolicy.Gpo[] 36 | 37 | .OUTPUTS 38 | System.Management.Automation.PSCustomObject 39 | 40 | .EXAMPLE 41 | C:\PS> Get-GPO -All | Get-GPSetting -Verbose -OutVariable MyGPOs 42 | 43 | .EXAMPLE 44 | C:\PS> Get-GPO 'DriveMapping' | Get-GPSetting -Type DriveMapping 45 | 46 | Name : DriveMapping 47 | ConfigurationGroup : User 48 | SettingChanged : 2017-10-03 18:20:54 49 | Order : 1 50 | DriveAction : Replace 51 | ShowThisDrive : True 52 | ShowAllDrives : True 53 | Label : MyUser 54 | Path : \\MyServerA\ShareB 55 | Reconnect : True 56 | FirstAvailableLetter : False 57 | DriveLetter : P 58 | ConnectUserName : 59 | Filters : CONTOSO\MyUsers 60 | 61 | Name : DriveMapping 62 | ConfigurationGroup : User 63 | SettingChanged : 2017-10-03 18:20:57 64 | Order : 2 65 | DriveAction : Replace 66 | ShowThisDrive : True 67 | ShowAllDrives : True 68 | Label : Department 69 | Path : \\DeptServer\ShareB 70 | Reconnect : True 71 | FirstAvailableLetter : False 72 | DriveLetter : S 73 | ConnectUserName : 74 | Filters : CONTOSO\DeptUsers 75 | 76 | .EXAMPLE 77 | C:\PS> Get-GPO 'Workstation Scripts' | Get-GPSetting -Type Script | Sort-Object -Property Type,Order | Format-Table -AutoSize 78 | 79 | Name ConfigurationGroup Script Type Parameters Order PSRunOrder 80 | ---- ------------------ ------ ---- ---------- ----- ---------- 81 | Workstation Scripts Computer CleanTempFiles.cmd Shutdown 0 PSNotConfigured 82 | Workstation Scripts Computer ComputerInventory.ps1 Startup 0 RunPSFirst 83 | Workstation Scripts Computer InstallApps.cmd Startup 1 RunPSFirst 84 | Workstation Scripts Computer ClearAppCache.vbs Startup 2 RunPSFirst 85 | 86 | .LINK 87 | https://github.com/thedavecarroll/PoShGroupPolicy 88 | 89 | #> 90 | [CmdLetBinding()] 91 | param( 92 | [ValidateNotNullOrEmpty()] 93 | [Parameter(ValueFromPipeline)] 94 | [Microsoft.GroupPolicy.Gpo[]]$GroupPolicy, 95 | 96 | #[ValidateSet('ExtensionType','Script','DriveMapSetting','SecuritySetting','RegistrySetting','FolderRedirectionSetting')] 97 | [ValidateNotNullOrEmpty()] 98 | [String]$Type#='ExtensionType' 99 | ) 100 | 101 | begin { 102 | 103 | Write-Verbose -Message 'Importing Group Policy module...' 104 | try { 105 | Import-Module -Name GroupPolicy -Verbose:$false -ErrorAction stop 106 | } 107 | catch { 108 | Write-Warning -Message 'Failed to import GroupPolicy module' 109 | exit 1 110 | } 111 | 112 | $Timer = [System.Diagnostics.Stopwatch]::StartNew() 113 | $Counter = 0 114 | $TotalCount = $GroupPolicy.Count 115 | 116 | } 117 | 118 | process { 119 | 120 | foreach ($GPO in $GroupPolicy) { 121 | 122 | $Counter++ 123 | if ($VerbosePreference -eq 'Continue' -and $TotalCount -gt 1) { 124 | Write-Verbose -Message "Generating XML report to parse GPO $($GPO.DisplayName)" 125 | Write-Progress -Activity "Processing..." -CurrentOperation $GPO.DisplayName -Status "$Counter / $TotalCount" 126 | } 127 | 128 | try { 129 | [xml]$GpoXml = $GPO.GenerateReport('Xml') 130 | } 131 | catch { 132 | Write-Warning -Message 'Unable to generate XML report' 133 | Write-Warning -Message $_.Exception.Message 134 | continue 135 | } 136 | 137 | $XmlNamespaceManager = [System.Xml.XmlNamespaceManager]::New($GpoXml.CreateNavigator().NameTable) 138 | $XmlNamespaces = $GpoXml.CreateNavigator().GetNamespacesInScope('All') 139 | foreach ($key in $XmlNamespaces.keys) { 140 | $XmlNamespaceManager.AddNamespace( $key, $XmlNamespaces.$key ) 141 | } 142 | $XmlNamespaceManager.AddNamespace('gp','http://www.microsoft.com/GroupPolicy/Settings') 143 | 144 | #$ExtensionNodes = $GpoXml.SelectNodes("/gp:GPO//gp:ExtensionData[gp:Name = '$Type']/gp:Extension", $XmlNamespaceManager) 145 | $ExtensionNodes = $GpoXml.SelectNodes("/gp:GPO//gp:ExtensionData/gp:Extension", $XmlNamespaceManager) 146 | $ExtensionNodes = $GpoXml.SelectNodes("//gp:ExtensionData/gp:Extension", $XmlNamespaceManager) 147 | 148 | $GPConfiguration = foreach ($Node in $ExtensionNodes.ChildNodes) { 149 | 150 | $Properties = $Node | Get-Member -MemberType Property | Select-Object -ExpandProperty Name -Unique 151 | $Settings = $Node | Select-Object -Property $Properties 152 | 153 | $TypeName = (($Node.NamespaceURI -Split '/' | Select-Object -Skip 3) -Join '.') + '.' + $Node.LocalName 154 | 155 | foreach ($Setting in $Settings) { 156 | 157 | $GPSettings = [PsCustomObject]@{ 158 | GpoName = $Node.ParentNode.ParentNode.ParentNode.ParentNode.Name 159 | Guid = $Node.ParentNode.ParentNode.ParentNode.ParentNode.Identifier.Identifier.InnerText 160 | DomainName = $Node.ParentNode.ParentNode.ParentNode.ParentNode.Identifier.Domain.InnerText 161 | CreatedTime = $Node.ParentNode.ParentNode.ParentNode.ParentNode.CreatedTime 162 | ModifiedTime = $Node.ParentNode.ParentNode.ParentNode.ParentNode.ModifiedTime 163 | ReadTime = $Node.ParentNode.ParentNode.ParentNode.ParentNode.ReadTime 164 | #ComputerConfiguration = if ($Node.ParentNode.ParentNode.ParentNode.ParentNode.Computer.Enabled) { $true } else { $false } 165 | #UserConfiguration = if ($Node.ParentNode.ParentNode.ParentNode.ParentNode.User.Enabled) { $true } else { $false } 166 | #LinksTo = $Node.ParentNode.ParentNode.ParentNode.ParentNode. LinksTo 167 | Configuration = $Node.ParentNode.ParentNode.ParentNode.Name 168 | ExtensionType = $Node.NamespaceURI.Split('/')[-1] 169 | XmlNamespace = $Node.NamespaceURI 170 | TypeName = $TypeName 171 | LocalName = $Node.LocalName 172 | Node = $Node 173 | } 174 | 175 | $GPSettings.PsObject.TypeNames.Insert(0,$TypeName) 176 | 177 | foreach ($Property in $Properties) { 178 | if ($Property -eq 'Member') { 179 | $Members = @() 180 | foreach ($Member in $Node.Member.ChildNodes) { 181 | if ($Member.PreviousSibling -eq $null -and $Member.NextSibling -ne $null) { 182 | $Members += [PsCustomObject]@{ 183 | #$($Member.Name) = $Member.InnerText 184 | #$($Member.NextSibling.Name) = $Member.NextSibling.InnerText 185 | (Get-Culture).TextInfo.totitlecase($Member.InnerText.ToLower()).Replace(' ','') = $Member.NextSibling.InnerText 186 | } 187 | } 188 | } 189 | 190 | Add-Member -InputObject $GPSettings -MemberType NoteProperty -Name Members -Value $Members -Force 191 | } 192 | 193 | switch ($Property) { 194 | 'Name' { 195 | Add-Member -InputObject $GPSettings -MemberType NoteProperty -Name 'PolicyName' -Value $Setting.$Property -Force 196 | } 197 | 'EditText' { 198 | $EditTextProperties = $Setting.$Property | Get-Member -MemberType Property | Select-Object -ExpandProperty Name -Unique 199 | $Policies = $Setting.$Property | Select-Object -Property $EditTextProperties 200 | Add-Member -InputObject $GPSettings -MemberType NoteProperty -Name 'Settings' -Value $Policies -Force 201 | } 202 | 'Checkbox' { 203 | $CheckboxProperties = $Setting.$Property | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name -Unique 204 | $Policies = $Setting.$Property | Select-Object -Property $CheckboxProperties 205 | Add-Member -InputObject $GPSettings -MemberType NoteProperty -Name 'CheckboxSettings' -Value $Policies -Force 206 | } 207 | 'Numeric' { 208 | $NumericProperties = $Setting.$Property | Get-Member -MemberType Property | Select-Object -ExpandProperty Name -Unique 209 | $Policies = $Setting.$Property | Select-Object -Property $NumericProperties 210 | Add-Member -InputObject $GPSettings -MemberType NoteProperty -Name 'NumericSettings' -Value $Policies -Force 211 | } 212 | 'DropDownList' { 213 | $NumericProperties = $Setting.$Property | Get-Member -MemberType Property | Select-Object -ExpandProperty Name -Unique 214 | $Policies = $Setting.$Property | Select-Object -Property $NumericProperties 215 | Add-Member -InputObject $GPSettings -MemberType NoteProperty -Name 'DropDownLists' -Value $Policies -Force 216 | } 217 | 'Member' { 218 | 219 | } 220 | default { 221 | Add-Member -InputObject $GPSettings -MemberType NoteProperty -Name $Property -Value $Setting.$Property -Force 222 | } 223 | } 224 | } 225 | 226 | $Value = $Node.ChildNodes.ChildNodes.ChildNodes | Where-Object { $_.'#text' } | Select-Object -ExpandProperty '#text' 227 | if ($Value) { 228 | Add-Member -InputObject $GPSettings -MemberType NoteProperty -Name Value -Value $Value -Force 229 | } 230 | 231 | } 232 | 233 | $GPConfiguration 234 | 235 | } # end foreach node loop 236 | 237 | } # end foreach GPO loop 238 | 239 | } 240 | 241 | end { 242 | Write-Verbose -Message "Successfully processed $($GPO.count) Group Policies." 243 | Write-Verbose -Message "Completed in $([system.String]::Format("{0}d {1:00}h:{2:00}m:{3:00}s.{4:00}", $Timer.Elapsed.Days, $Timer.Elapsed.Hours, $Timer.Elapsed.Minutes, $Timer.Elapsed.Seconds, $Timer.Elapsed.Milliseconds / 10))" 244 | } 245 | } 246 | 247 | 248 | <# 249 | 250 | 251 | 252 | 253 | 254 | switch ($Type) { 255 | 'ExtensionType' { 256 | foreach ($Extension in $GpoXml.GPO.Computer.ExtensionData.Extension) { 257 | [PsCustomObject]@{ 258 | Name = $GpoName 259 | DomainName = $GPO.DomainName 260 | ConfigurationGroup = 'Computer' 261 | CreatedTime = $CreatedTime 262 | ModifiedTime = $ModifiedTime 263 | ExtensionType = $Extension.Type.Split(":")[1] 264 | } 265 | } 266 | foreach ($Extension in $GpoXml.GPO.User.ExtensionData.Extension) { 267 | [PsCustomObject]@{ 268 | Name = $GpoName 269 | DomainName = $GPO.DomainName 270 | ConfigurationGroup = 'User' 271 | CreatedTime = $CreatedTime 272 | ModifiedTime = $ModifiedTime 273 | ExtensionType = $Extension.Type.Split(":")[1] 274 | } 275 | } 276 | 277 | } 278 | 'Script' { 279 | foreach ($Script in $Gpoxml.GPO.Computer.ExtensionData.Extension.Script ) { 280 | if ($Script) { 281 | [PsCustomObject]@{ 282 | Name = $GpoName 283 | ConfigurationGroup = 'Computer' 284 | Script = $Script.Command 285 | Type = $Script.Type 286 | Parameters = $Script.Parameters 287 | Order = $Script.Order 288 | PSRunOrder = $Script.RunOrder 289 | } 290 | } 291 | } 292 | foreach ($Script in $Gpoxml.GPO.User.ExtensionData.Extension.Script ) { 293 | if ($Script) { 294 | [PsCustomObject]@{ 295 | Name = $GpoName 296 | ConfigurationGroup = 'User' 297 | Script = $Script.Command 298 | Type = $Script.Type 299 | Parameters = $Script.Parameters 300 | Order = $Script.Order 301 | PSRunOrder = $Script.RunOrder 302 | } 303 | } 304 | } 305 | } 306 | 'DriveMapSetting' { 307 | foreach ($DriveMapping in $Gpoxml.GPO.Computer.ExtensionData.Extension.DriveMapSettings.Drive ) { 308 | if ($DriveMapping) { 309 | switch ($DriveMapping.Properties.action) { 310 | 'R' { $DriveAction = 'Replace'} 311 | 'U' { $DriveAction = 'Update'} 312 | 'C' { $DriveAction = 'Create'} 313 | 'D' { $DriveAction = 'Delete'} 314 | } 315 | if ($DriveMapping.Properties.persistent -eq 1) { 316 | $Reconnect = $true 317 | } else { 318 | $Reconnect = $false 319 | } 320 | if ($DriveMapping.Filters) { 321 | $Filters = $DriveMapping.Filters.FilterGroup.Name 322 | } else { 323 | $Filters = $null 324 | } 325 | if ($DriveMapping.Properties.thisDrive -eq 'SHOW') { 326 | $ShowThisDrive = $true 327 | } elseif ($DriveMapping.Properties.thisDrive -eq 'HIDE') { 328 | $ShowThisDrive = $false 329 | } else { 330 | $ShowThisDrive = $null 331 | } 332 | if ($DriveMapping.Properties.allDrives -eq 'SHOW') { 333 | $ShowAllDrives = $true 334 | } elseif ($DriveMapping.Properties.allDrives -eq 'HIDE') { 335 | $ShowAllDrives = $false 336 | } else { 337 | $ShowAllDrives = $null 338 | } 339 | if ($DriveMapping.Properties.useLetter -eq 0) { 340 | $FirstAvailableLetter = $true 341 | } else { 342 | $FirstAvailableLetter = $false 343 | } 344 | [PsCustomObject]@{ 345 | Name = $GpoName 346 | ConfigurationGroup = 'Computer' 347 | SettingChanged = $DriveMapping.Changed 348 | Order = $DriveMapping.GPOSettingOrder 349 | DriveAction = $DriveAction 350 | ShowThisDrive = $ShowThisDrive 351 | ShowAllDrives = $ShowAllDrives 352 | Label = $DriveMapping.Properties.label 353 | Path = $DriveMapping.Properties.path 354 | Reconnect = $Reconnect 355 | FirstAvailableLetter = $FirstAvailableLetter 356 | DriveLetter = $DriveMapping.Properties.letter 357 | ConnectUserName = $DriveMapping.Properties.userName 358 | Filters = $Filters 359 | } 360 | } 361 | } 362 | foreach ($DriveMapping in $Gpoxml.GPO.User.ExtensionData.Extension.DriveMapSettings.Drive ) { 363 | if ($DriveMapping) { 364 | switch ($DriveMapping.Properties.action) { 365 | 'R' { $DriveAction = 'Replace'} 366 | 'U' { $DriveAction = 'Update'} 367 | 'C' { $DriveAction = 'Create'} 368 | 'D' { $DriveAction = 'Delete'} 369 | } 370 | if ($DriveMapping.Properties.persistent -eq 1) { 371 | $Reconnect = $true 372 | } else { 373 | $Reconnect = $false 374 | } 375 | if ($DriveMapping.Filters) { 376 | $Filters = $DriveMapping.Filters.FilterGroup.Name 377 | } else { 378 | $Filters = $null 379 | } 380 | if ($DriveMapping.Properties.thisDrive -eq 'SHOW') { 381 | $ShowThisDrive = $true 382 | } elseif ($DriveMapping.Properties.thisDrive -eq 'HIDE') { 383 | $ShowThisDrive = $false 384 | } else { 385 | $ShowThisDrive = $null 386 | } 387 | if ($DriveMapping.Properties.allDrives -eq 'SHOW') { 388 | $ShowAllDrives = $true 389 | } elseif ($DriveMapping.Properties.allDrives -eq 'HIDE') { 390 | $ShowAllDrives = $false 391 | } else { 392 | $ShowAllDrives = $null 393 | } 394 | if ($DriveMapping.Properties.useLetter -eq 0) { 395 | $FirstAvailableLetter = $true 396 | } else { 397 | $FirstAvailableLetter = $false 398 | } 399 | [PsCustomObject]@{ 400 | Name = $GpoName 401 | ConfigurationGroup = 'User' 402 | SettingChanged = $DriveMapping.Changed 403 | Order = $DriveMapping.GPOSettingOrder 404 | DriveAction = $DriveAction 405 | ShowThisDrive = $ShowThisDrive 406 | ShowAllDrives = $ShowAllDrives 407 | Label = $DriveMapping.Properties.label 408 | Path = $DriveMapping.Properties.path 409 | Reconnect = $Reconnect 410 | FirstAvailableLetter = $FirstAvailableLetter 411 | DriveLetter = $DriveMapping.Properties.letter 412 | ConnectUserName = $DriveMapping.Properties.userName 413 | Filters = $Filters 414 | } 415 | } 416 | } 417 | } 418 | 'SecuritySetting' { 419 | foreach ($SecuritySetting in $Gpoxml.GPO.Computer.ExtensionData.Extension.SecurityOptions ) { 420 | if ($SecuritySetting) { 421 | [PsCustomObject]@{ 422 | Name = $GpoName 423 | ConfigurationGroup = 'Computer' 424 | KeyName = $SecuritySetting.KeyName 425 | SettingNumber = $SecuritySetting.SettingNumber 426 | Display = $SecuritySetting.Display.Name 427 | Units = $SecuritySetting.Display.Units 428 | } 429 | } 430 | } 431 | foreach ($SecuritySetting in $Gpoxml.GPO.User.ExtensionData.Extension.SecurityOptions ) { 432 | if ($SecuritySetting) { 433 | [PsCustomObject]@{ 434 | Name = $GpoName 435 | ConfigurationGroup = 'User' 436 | KeyName = $SecuritySetting.KeyName 437 | SettingNumber = $SecuritySetting.SettingNumber 438 | Display = $SecuritySetting.Display.Name 439 | Units = $SecuritySetting.Display.Units 440 | } 441 | } 442 | } 443 | } 444 | 'RegistrySetting' { 445 | foreach ($RegistrySetting in $Gpoxml.Computer.ExtensionData.Extension.Policy ) { 446 | if ($RegistrySetting) { 447 | $GPORegistrySettingsInfo += [PsCustomObject]@{ 448 | Name = $GpoName 449 | ConfigurationGroup = 'Computer' 450 | PolicyName = $RegistrySetting.Name 451 | State = $RegistrySetting.State 452 | Supported = $RegistrySetting.Supported 453 | } 454 | } 455 | } 456 | foreach ($RegistrySetting in $Gpoxml.User.ExtensionData.Extension.Policy ) { 457 | if ($RegistrySetting) { 458 | $GPORegistrySettingsInfo += [PsCustomObject]@{ 459 | Name = $GpoName 460 | ConfigurationGroup = 'User' 461 | PolicyName = $RegistrySetting.Name 462 | State = $RegistrySetting.State 463 | Supported = $RegistrySetting.Supported 464 | } 465 | } 466 | } 467 | } 468 | 'FolderRedirectionSetting' { 469 | try { 470 | $KnownFolders = Get-GPKnownFolderId -ErrorAction Stop 471 | foreach ($FolderRedirectionSetting in $Gpoxml.Computer.ExtensionData.Extension.Folder ) { 472 | if ($FolderRedirectionSetting) { 473 | $GPOFolderRedirectionSettingsInfo += [PsCustomObject]@{ 474 | Name = $GpoName 475 | ConfigurationGroup = 'Computer' 476 | Id = $FolderRedirectionSetting.Id 477 | DisplayName = $KnownFolders | Where-Object {$_.GUID -eq $FolderRedirectionSetting.Id} | Select-Object -ExpandProperty DisplayName 478 | FolderType = $KnownFolders | Where-Object {$_.GUID -eq $FolderRedirectionSetting.Id} | Select-Object -ExpandProperty FolderType 479 | DefaultPath = $KnownFolders | Where-Object {$_.GUID -eq $FolderRedirectionSetting.Id} | Select-Object -ExpandProperty DefaultPath 480 | DestinationPath = $FolderRedirectionSetting.Location.DestinationPath 481 | } 482 | } 483 | } 484 | foreach ($FolderRedirectionSetting in $Gpoxml.User.ExtensionData.Extension.Folder ) { 485 | if ($FolderRedirectionSetting) { 486 | $GPOFolderRedirectionSettingsInfo += [PsCustomObject]@{ 487 | Name = $GpoName 488 | ConfigurationGroup = 'User' 489 | Id = $FolderRedirectionSetting.Id 490 | DisplayName = $KnownFolders | Where-Object {$_.GUID -eq $FolderRedirectionSetting.Id} | Select-Object -ExpandProperty DisplayName 491 | FolderType = $KnownFolders | Where-Object {$_.GUID -eq $FolderRedirectionSetting.Id} | Select-Object -ExpandProperty FolderType 492 | DefaultPath = $KnownFolders | Where-Object {$_.GUID -eq $FolderRedirectionSetting.Id} | Select-Object -ExpandProperty DefaultPath 493 | DestinationPath = $FolderRedirectionSetting.Location.DestinationPath 494 | } 495 | } 496 | } 497 | } 498 | catch { 499 | Write-Warning -Message 'Unable to obtain list of KnownFolders.' 500 | } 501 | } 502 | } # end switch 503 | 504 | } # end foreach loop 505 | 506 | $xmlnsGpSettings = 'http://www.microsoft.com/GroupPolicy/Settings' 507 | $xmlnsSchemaInstance = 'http://www.w3.org/2001/XMLSchema-instance' 508 | $xmlnsSchema = 'http://www.w3.org/2001/XMLSchema' 509 | $ComputerConfiguration = 'gp:Computer/gp:ExtensionData/gp:Extension' 510 | $UserConfiguration = 'gp:User/gp:ExtensionData/gp:Extension' 511 | 512 | 513 | function Get-XmlNodeData { 514 | param ($ExtensionNodes) 515 | 516 | 517 | 518 | 519 | } 520 | 521 | $Drives = foreach ($node in $extensionNodes.ChildNodes) { $Props = $node | Get-Member -MemberType Property | Select-Object -ExpandProperty Name -Unique ; $node | select -Property $Props} 522 | PS C:\PowerShell\Temp> $Drives[0] 523 | 524 | clsid Drive 525 | ----- ----- 526 | {8FDDCC1A-0C3C-43cd-A6B4-71A6DF20DA8C} {T:, P:} 527 | 528 | 529 | PS C:\PowerShell\Temp> $Drives.Drive 530 | 531 | $extensionNodes[0].ChildNodes 532 | foreach ($node in $extensionNodes.ChildNodes) { $Node | Get-Member -MemberType Property | Select-Object -ExpandProperty Name } 533 | #Display 534 | #KeyName 535 | #SettingNumber 536 | 537 | (Get-Culture).textinfo.totitlecase('Path to theme file'.tolower()).Replace(' ','') 538 | 539 | 540 | #> -------------------------------------------------------------------------------- /PoShGroupPolicy/Scripts/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thedavecarroll/PoShGroupPolicy/191c3715396a9721bc3970d579acede807d785b5/PoShGroupPolicy/Scripts/.gitignore -------------------------------------------------------------------------------- /PoShGroupPolicy/TypeData/PoShGroupPolicy.Format.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GroupPolicy.Settings.Registry.Policy.List 6 | 7 | GroupPolicy.Settings.Registry.Policy 8 | 9 | 10 | 11 | 12 | 13 | 14 | GpoName 15 | 16 | 17 | DomainName 18 | 19 | 20 | Configuration 21 | 22 | 23 | ExtensionType 24 | 25 | 26 | Category 27 | 28 | 29 | PolicyName 30 | 31 | 32 | State 33 | 34 | 35 | Supported 36 | 37 | 38 | 39 | if ($_.Settings) { ($_.Settings | Format-List | Out-String).Trim() } 40 | 41 | 42 | 43 | if ($_.CheckboxSettings) { ($_.CheckboxSettings | Format-List | Out-String).Trim() } 44 | 45 | 46 | 47 | if ($_.NumericSettings) { ($_.NumericSettings | Format-List | Out-String).Trim() } 48 | 49 | 50 | 51 | if ($_.DropDownLists) { ($_.DropDownLists | Format-List | Out-String).Trim() } 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | GroupPolicy.Settings.Registry.Policy.Table 60 | 61 | GroupPolicy.Settings.Registry.Policy 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | GpoName 77 | 78 | 79 | DomainName 80 | 81 | 82 | Configuration 83 | 84 | 85 | ExtensionType 86 | 87 | 88 | PolicyName 89 | 90 | 91 | Category 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /PoShGroupPolicy/TypeData/PoShGroupPolicy.Types.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GroupPolicy.Settings.Registry.Policy 5 | 6 | 7 | PSStandardMembers 8 | 9 | 10 | DefaultDisplayPropertySet 11 | 12 | GpoName 13 | DomainName 14 | Configuration 15 | ExtensionType 16 | Category 17 | PolicyName 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /PoShGroupPolicy/en-US/about_PoShGroupPolicy.help.txt: -------------------------------------------------------------------------------- 1 | TOPIC 2 | PoShGroupPolicy 3 | 4 | SHORT DESCRIPTION 5 | PoShGroupPolicy is a PowerShell module for working with Active Directory Group Policy. 6 | 7 | LONG DESCRIPTION 8 | Have you ever needed to update a script that you knew was configured in a group policy, but you just didn't know 9 | which GPO? 10 | 11 | This module helps the by parsing the group policy and returing key pieces of data for several GP extension types. 12 | 13 | EXAMPLE 14 | C:\PS> Get-GPO 'Workstation Scripts' | Get-GPSetting -Type Script | Sort-Object -Property Type,Order | Format-Table -AutoSize 15 | 16 | Name ConfigurationGroup Script Type Parameters Order PSRunOrder 17 | ---- ------------------ ------ ---- ---------- ----- ---------- 18 | Workstation Scripts Computer CleanTempFiles.cmd Shutdown 0 PSNotConfigured 19 | Workstation Scripts Computer ComputerInventory.ps1 Startup 0 RunPSFirst 20 | Workstation Scripts Computer InstallApps.cmd Startup 1 RunPSFirst 21 | Workstation Scripts Computer ClearAppCache.vbs Startup 2 RunPSFirst 22 | 23 | SEE ALSO 24 | Get-GPSetting -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PoShGroupPolicy 0.4 2 | 3 | PowerShell module to assist with Group Policy 4 | 5 | ## Get the module 6 | 7 | PoShGroupPolicy can be downloaded or inspected at the [PowerShellGallery](https://www.powershellgallery.com/packages/PoShGroupPolicy). 8 | 9 | ## What GPO does that again? 10 | 11 | Have you ever need to update a script that you knew was configured in a group policy, but you just didn't know which 12 | GPO? This module helps the by parsing the group policy and returning key pieces of data for several GP extension types. 13 | 14 | ## Example 15 | 16 | ```powershell 17 | C:\PS> Get-GPO 'Workstation Scripts' | Get-GPSetting -Type Script | Sort-Object -Property Type,Order | Format-Table -AutoSize 18 | 19 | Name ConfigurationGroup Script Type Parameters Order PSRunOrder 20 | ---- ------------------ ------ ---- ---------- ----- ---------- 21 | Workstation Scripts Computer CleanTempFiles.cmd Shutdown 0 PSNotConfigured 22 | Workstation Scripts Computer ComputerInventory.ps1 Startup 0 RunPSFirst 23 | Workstation Scripts Computer InstallApps.cmd Startup 1 RunPSFirst 24 | Workstation Scripts Computer ClearAppCache.vbs Startup 2 RunPSFirst 25 | ``` 26 | 27 | ### Note 28 | 29 | This is my first public module on GitHub and I'm eager to learn. Feel free to submit suggestions and especially any 30 | corrections. Please watch or `Find-Module -Name PoshGroupPolicy` occassionally to see if I've published any updates. 31 | -------------------------------------------------------------------------------- /ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## 0.4 4 | 5 | * Get-GPSettings - corrected total count during verbose progress bar 6 | * Module help - updated section names 7 | * Module script - added #Requires -Modules GroupPolicy, cleanup export 8 | * Added TODO list 9 | * Restructured project scaffolding 10 | 11 | ## 0.3 12 | 13 | * Added release notes 14 | * Added context-based help for Get-GPSetting 15 | * Updated tagging 16 | * Updated module help and README.md 17 | * Updated output for Get-GPSetting 18 | 19 | ## 0.2 20 | 21 | * First real version that does something useful 22 | * Resequenced version number 23 | * Renamed Get-GPKnownFolder to Get-GPKnownFolderId and made a private function 24 | * First delivery of Get-GPSetting 25 | 26 | ## 1.0 27 | 28 | * First release just to prove that I could release a module to PowerShellGallery.com 29 | * I messed up on the version number 30 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # PoShGroupPolicy 2 | 3 | ## Changelog 4 | 5 | All notable changes to this project will be documented in this file. 6 | 7 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 8 | 9 | ## 0.4 10 | 11 | * Get-GPSettings - corrected total count during verbose progress bar 12 | * Module help - updated section names 13 | * Module script - added #Requires -Modules GroupPolicy, cleanup export 14 | * Added TODO list 15 | * Restructured project scaffolding 16 | 17 | ## 0.3 18 | 19 | * Added release notes 20 | * Added context-based help for Get-GPSetting 21 | * Updated tagging 22 | * Updated module help and README.md 23 | * Updated output for Get-GPSetting 24 | 25 | ## 0.2 26 | 27 | * First real version that does something useful 28 | * Resequenced version number 29 | * Renamed Get-GPKnownFolder to Get-GPKnownFolderId and made a private function 30 | * First delivery of Get-GPSetting 31 | 32 | ## 1.0 33 | 34 | * First release just to prove that I could release a module to PowerShellGallery.com 35 | * I messed up on the version number 36 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # PoShGroupPolicy 0.4 2 | 3 | PowerShell module to assist with Group Policy 4 | 5 | ## Get the module 6 | 7 | PoShGroupPolicy can be downloaded or inspected at the [PowerShellGallery](https://www.powershellgallery.com/packages/PoShGroupPolicy). 8 | 9 | ## What GPO does that again? 10 | 11 | Have you ever need to update a script that you knew was configured in a group policy, but you just didn't know which 12 | GPO? This module helps the by parsing the group policy and returning key pieces of data for several GP extension types. 13 | 14 | ## Example 15 | 16 | ```powershell 17 | C:\PS> Get-GPO 'Workstation Scripts' | Get-GPSetting -Type Script | Sort-Object -Property Type,Order | Format-Table -AutoSize 18 | 19 | Name ConfigurationGroup Script Type Parameters Order PSRunOrder 20 | ---- ------------------ ------ ---- ---------- ----- ---------- 21 | Workstation Scripts Computer CleanTempFiles.cmd Shutdown 0 PSNotConfigured 22 | Workstation Scripts Computer ComputerInventory.ps1 Startup 0 RunPSFirst 23 | Workstation Scripts Computer InstallApps.cmd Startup 1 RunPSFirst 24 | Workstation Scripts Computer ClearAppCache.vbs Startup 2 RunPSFirst 25 | ``` 26 | 27 | ### Note 28 | 29 | This is my first public module on GitHub and I'm eager to learn. Feel free to submit suggestions and especially any 30 | corrections. Please watch or `Find-Module -Name PoshGroupPolicy` occasionally to see if I've published any updates. 31 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs-material -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | # Project Info 2 | site_name: PoShGroupPolicy 3 | site_description: Online Help for PoShGroupPolicy PowerShell Module 4 | site_author: Dave Carroll 5 | site_url: https://poshgrouppolicy.anovelidea.org 6 | 7 | # Repo Info 8 | repo_name: thedavecarroll/PoShGroupPolicy 9 | repo_url: https://github.com/thedavecarroll/PoShGroupPolicy 10 | 11 | # Copyright 12 | copyright: "Copyright © 2018-2020 Dave Carroll
PoShGroupPolicy is licensed under the MIT license." 13 | 14 | # Analytics 15 | google_analytics: 16 | - UA-122236350-2 17 | - auto 18 | 19 | # Configuration 20 | theme: 21 | name: material 22 | edit_uri: edit/master/docs/ 23 | 24 | # Customization 25 | extra: 26 | social: 27 | - type: github 28 | link: https://github.com/thedavecarroll/ 29 | - type: twitter 30 | link: https://twitter.com/thedavecarroll 31 | - type: linkedin 32 | link: https://www.linkedin.com/in/thedavecarroll/ 33 | 34 | # Extensions 35 | markdown_extensions: 36 | - admonition 37 | - pymdownx.superfences 38 | - pymdownx.emoji 39 | - pymdownx.tasklist 40 | - pymdownx.mark 41 | - pymdownx.keys 42 | - pymdownx.details 43 | - pymdownx.critic 44 | - codehilite: 45 | guess_lang: true 46 | - toc: 47 | permalink: true 48 | 49 | # Navigation 50 | nav: 51 | - Home: README.md 52 | - Change Log: CHANGELOG.md 53 | - Functions: 54 | - Get-GPSetting: Get-GPSetting.md 55 | --------------------------------------------------------------------------------