├── License ├── PowerShellModule ├── License ├── PowerShellModule.psd1 ├── PowerShellModule.psm1 └── Readme.md └── README.md /License: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2017] [David O'Brien] 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 | -------------------------------------------------------------------------------- /PowerShellModule/License: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2017] [David O'Brien] 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 | -------------------------------------------------------------------------------- /PowerShellModule/PowerShellModule.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidobrien1985/DscResources/8e49997befcbb2d9674a1cf3ffe68591801c5cd2/PowerShellModule/PowerShellModule.psd1 -------------------------------------------------------------------------------- /PowerShellModule/PowerShellModule.psm1: -------------------------------------------------------------------------------- 1 | enum ensure { 2 | absent 3 | present 4 | } 5 | 6 | enum scope { 7 | allusers 8 | currentuser 9 | } 10 | 11 | enum installationpolicy 12 | { 13 | trusted 14 | untrusted 15 | } 16 | 17 | [DscResource()] 18 | class PSModuleResource { 19 | 20 | [DscProperty(Key)] 21 | [string]$Module_Name 22 | 23 | [DscProperty(Mandatory=$false)] 24 | [Ensure]$Ensure = [ensure]::present 25 | 26 | [DscProperty(Mandatory=$false)] 27 | [string]$RequiredVersion 28 | 29 | [DscProperty(Mandatory=$false)] 30 | [string]$MinimumVersion 31 | 32 | [DscProperty(Mandatory=$false)] 33 | [string]$MaximumVersion 34 | 35 | [DscProperty(Mandatory=$false)] 36 | [scope]$InstallScope = [scope]::allusers 37 | 38 | [DscProperty(Mandatory=$false)] 39 | [string]$Repository = 'PSGallery' 40 | 41 | [DscProperty(Mandatory=$false)] 42 | [bool]$AllowClobber = $false 43 | 44 | [DscProperty(Mandatory=$false)] 45 | [pscredential]$Credential 46 | 47 | [PSModuleResource] Get() { 48 | 49 | $state = [hashtable]::new() 50 | $state.Module_Name = $this.Module_Name 51 | $Module = Get-Module -Name $this.Module_Name -ListAvailable -ErrorAction Ignore 52 | if ($Module) { 53 | $state.Ensure = [ensure]::present 54 | } 55 | else { 56 | $state.Ensure = [ensure]::absent 57 | } 58 | 59 | return [PSModuleResource]$state 60 | 61 | } 62 | 63 | 64 | [void] Set() { 65 | 66 | if ($this.Ensure -eq 'present') { 67 | try { 68 | $arguments = $this.GetVersionArguments() 69 | $arguments += @{"-Name" = $this.Module_Name; "-ErrorAction" = "Stop"; "-Repository" = $this.Repository} 70 | if ($this.Credential) { 71 | $arguments += @{"-Credential" = $this.Credential} 72 | } 73 | Find-Module @arguments 74 | } 75 | catch { 76 | Write-Error -ErrorRecord $_ 77 | throw $_ 78 | } 79 | 80 | try { 81 | $arguments = $this.GetVersionArguments() 82 | $arguments += @{"-Name" = $this.Module_Name; "-Force" = $true; "-Scope" = $this.InstallScope; "-Repository" = $this.Repository} 83 | if ($this.AllowClobber) { 84 | $arguments += @{"-AllowClobber" = $this.AllowClobber} 85 | } 86 | if ($this.Credential) { 87 | $arguments += @{"-Credential" = $this.Credential} 88 | } 89 | Install-Module @arguments 90 | } 91 | catch { 92 | Write-Error -ErrorRecord $_ 93 | } 94 | } 95 | elseif ($this.Ensure -eq 'absent') { 96 | $arguments = $this.GetVersionArguments() 97 | $arguments += @{"-Name" = $this.Module_Name; "-Force" = $true} 98 | Uninstall-Module @arguments 99 | } 100 | else { 101 | throw [System.ArgumentOutOfRangeException] "Value '$($this.Ensure)' of property Ensure is outside the range of allowed values" 102 | } 103 | } 104 | 105 | [bool] Test() { 106 | 107 | $modules = @() 108 | $modules += @(Get-Module -Name $this.Module_Name -ListAvailable -ErrorAction Ignore) 109 | $returnVal = $false 110 | 111 | Write-Verbose "The following versions of $($this.Module_Name) are installed" 112 | foreach ($module in $modules) 113 | { 114 | Write-Verbose "Module: $($this.Module_Name), Version: $($module.Version)" 115 | } 116 | 117 | # When no modules with that name were found 118 | if ($modules.Count -eq 0) 119 | { 120 | return ($this.Ensure -eq 'absent') 121 | } 122 | 123 | # We've found one or more matching modules, if neither RequiredVersion, MinimumVersion nor MaximumVersion is specified 124 | if ((-not $this.RequiredVersion) -and (-not $this.MinimumVersion) -and (-not $this.MaximumVersion)) 125 | { 126 | return ($this.Ensure -eq 'present') 127 | } 128 | 129 | # We've found one or more modules, check if RequiredVersion is set 130 | if ($this.RequiredVersion) 131 | { 132 | $modules | Where-Object { [System.Version]$_.Version -eq [System.Version]$this.RequiredVersion } | % { 133 | $returnVal = ($this.Ensure -eq 'present') 134 | } 135 | } 136 | 137 | # We've found one or more modules but RequiredVersion is not set, check MinimumVersion and MaximumVersion 138 | if ($this.MinimumVersion -and $this.MaximumVersion) 139 | { 140 | $modules | Where-Object { ([System.Version]$_.Version -ge [System.Version]$this.MinimumVersion) -and ([System.Version]$_.Version -le [System.Version]$this.MaximumVersion) } | % { 141 | $returnVal = ($this.Ensure -eq 'present') 142 | } 143 | } 144 | elseif ($this.MinimumVersion) { 145 | $modules | Where-Object { [System.Version]$_.Version -ge [System.Version]$this.MinimumVersion } | % { 146 | $returnVal = ($this.Ensure -eq 'present') 147 | } 148 | } 149 | elseif ($this.MaximumVersion) { 150 | $modules | Where-Object { [System.Version]$_.Version -le [System.Version]$this.MaximumVersion } | % { 151 | $returnVal = ($this.Ensure -eq 'present') 152 | } 153 | } 154 | 155 | return $returnVal 156 | } 157 | 158 | [hashtable] GetVersionArguments() { 159 | 160 | if ($this.RequiredVersion -and ($this.MaximumVersion -or $this.MinimumVersion)) 161 | { 162 | throw [System.ArgumentException] "The RequiredVersion argument is mutually exclusive to the MaximumVersion and MinimumVersion" 163 | } 164 | 165 | $versionArgs = [hashtable]::new() 166 | 167 | if ($this.RequiredVersion) 168 | { 169 | $versionArgs.Add("-RequiredVersion", $this.RequiredVersion) 170 | } 171 | else { 172 | if ($this.MinimumVersion) 173 | { 174 | $versionArgs.Add("-MinimumVersion", $this.MinimumVersion) 175 | } 176 | if ($this.MaximumVersion) 177 | { 178 | $versionArgs.Add("-MaximumVersion", $this.MaximumVersion) 179 | } 180 | } 181 | return $versionArgs 182 | } 183 | } 184 | 185 | [DscResource()] 186 | class PSModuleRepositoryResource { 187 | 188 | [DscProperty(Key)] 189 | [string]$Name 190 | 191 | [DscProperty(Mandatory=$false)] 192 | [Ensure]$Ensure = [ensure]::present 193 | 194 | [DscProperty(Mandatory=$false)] 195 | [string]$InstallationPolicy = [installationpolicy]::untrusted 196 | 197 | [DscProperty(Mandatory)] 198 | [string]$SourceLocation 199 | 200 | [DscProperty(Mandatory=$false)] 201 | [string]$PublishLocation 202 | 203 | [DscProperty(Mandatory=$false)] 204 | [pscredential]$Credential 205 | 206 | [PSModuleRepositoryResource] Get() { 207 | $state = [hashtable]::new() 208 | $state.Name = $this.Name 209 | $repository = Get-PSRepository -Name $this.Name -ErrorAction Ignore 210 | if ($repository) 211 | { 212 | $state.Ensure = [ensure]::present 213 | } 214 | else { 215 | $state.Ensure = [ensure]::absent 216 | } 217 | return [PSModuleRepositoryResource]$state 218 | } 219 | 220 | [void] Set() { 221 | 222 | $repository = Get-PSRepository -Name $this.Name -ErrorAction Ignore 223 | 224 | if ($this.Ensure -eq 'present') 225 | { 226 | $arguments = @{"-Name" = $this.Name; "-InstallationPolicy" = $this.InstallationPolicy; "-SourceLocation" = $this.SourceLocation} 227 | if ($this.PublishLocation) 228 | { 229 | $arguments.Add("-PublishLocation", $this.PublishLocation) 230 | } 231 | if ($this.Credential) { 232 | $arguments.Add("-Credential", $this.Credential) 233 | } 234 | if ($repository) 235 | { 236 | Set-PSRepository @arguments 237 | } 238 | else { 239 | Register-PSRepository @arguments 240 | } 241 | } 242 | elseif ($this.Ensure -eq 'absent') { 243 | Unregister-PSRepository -Name $this.Name 244 | } 245 | else { 246 | throw [System.ArgumentOutOfRangeException] "Value '$($this.Ensure)' of property Ensure is outside the range of allowed values" 247 | } 248 | } 249 | 250 | [bool] Test() { 251 | 252 | $repository = Get-PSRepository -Name $this.Name -ErrorAction Ignore 253 | 254 | if ($repository) 255 | { 256 | Write-Verbose "Found existing repository with name '$($repository.Name)'" 257 | if ($this.Ensure -eq 'present') 258 | { 259 | if (($repository.InstallationPolicy -eq $this.InstallationPolicy) -and ($repository.SourceLocation -eq $this.SourceLocation) -and ($repository.PublishLocation -eq $this.PublishLocation)) 260 | { 261 | return $true 262 | } 263 | } 264 | return $false 265 | } 266 | else { 267 | Write-Verbose "Could not find an existing repository with name '$($this.Name)'" 268 | return ($this.Ensure -eq 'absent') 269 | } 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /PowerShellModule/Readme.md: -------------------------------------------------------------------------------- 1 | # Description: 2 | This PowerShell DSC resource will download or remove PowerShell modules to or from a machine. 3 | 4 | It uses WMF 5 functionality (Find-Module, Install-Module, Uninstall-Module) to handle modules uploaded to the Microsoft PowerShell Gallery. (http://www.powershellgallery.com) 5 | 6 | ## The module contains the following resources: 7 | 8 | ### PSModuleResource 9 | - **`[String]` Module_Name** (_Key_): The name of the module 10 | - **`[String]` Ensure** (_Write_): Ensure that the module is present or absent { *Present* | Absent }. Defaults to Present. 11 | - **`[String]` RequiredVersion** (_Write_) : The RequiredVersion of the module. RequiredVersion is mutually exclusive to the MinimumVersion and MaximumVersion 12 | - **`[String]` MinimumVersion** (_Write_) : The MinimumVersion of the module 13 | - **`[String]` MaximumVersion** (_Write_) : The MaximumVersion of the module 14 | - **`[String]` InstallScope** (_Write_) : The scope in which to install the module { *allusers* | currentuser }. Defaults to allusers 15 | - **`[String]` Repository** (_Write_) : The name of a registered repository from which to download the module. Defaults to PSGallery. To register a new repository use the PSModuleRepositoryResource 16 | - **`[Bool]` AllowClobber** (_Write_) : Set to $true to pass the AllowClobber Parameter to Install-Module 17 | 18 | 19 | ### PSModuleRepositoryResource 20 | - **`[String]` Name** (_Key_): The name of the repository 21 | - **`[String]` Ensure** (_Write_): Ensure that the module is present or absent { *Present* | Absent }. Defaults to Present. 22 | - **`[String]` InstallationPolicy** (_Write_): Whether the repository should be trusted or untrusted { Trusted | *Untrusted* }. Defaults to untrusted. 23 | - **`[String]` SourceLocation** (_Required_): The location from where modules should be downloaded 24 | - **`[String]` PublishLocation** (_Write_): The location to where modules should be published 25 | 26 | # Usage: 27 | 28 | In DSC document: 29 | ````powershell 30 | 31 | Configuration MyConfig 32 | { 33 | Import-Dscresource -ModuleName PowerShellModule 34 | 35 | PSModuleResource AzureExt 36 | { 37 | Ensure = 'present' 38 | Module_Name = 'AzureExt' 39 | } 40 | 41 | } 42 | ```` 43 | Via Invoke-DscResource: 44 | ````powershell 45 | Invoke-DscResource -Name PSModuleResource -Method Set -ModuleName PowerShellModule -Property @{Ensure='absent';Module_Name='AzureExt'} -Verbose 46 | ```` 47 | Using RequiredVersion 48 | ````powershell 49 | PSModuleResource AzureExt 50 | { 51 | Ensure = 'present' 52 | Module_Name = 'AzureExt' 53 | RequiredVersion = '1.0.0.0' 54 | } 55 | ```` 56 | Using MinimumVersion and MaximumVersion (mutually exclusive to RequiredVersion) 57 | ````powershell 58 | PSModuleResource AzureExt 59 | { 60 | Ensure = 'present' 61 | Module_Name = 'AzureExt' 62 | MinimumVersion = '1.0.0.0' 63 | MaximumVersion = '2.0.0.0' 64 | } 65 | ```` 66 | Installing modules into different scopes ('allusers' or 'currentuser'). Default is 'allusers' 67 | ````powershell 68 | PSModuleResource AzureExt 69 | { 70 | Ensure = 'present' 71 | Module_Name = 'AzureExt' 72 | MinimumVersion = '1.0.0.0' 73 | MaximumVersion = '2.0.0.0' 74 | InstallScope = 'allusers' 75 | } 76 | ```` 77 | Using a custom repository by depending on the repository resource 78 | ````powershell 79 | PSModuleRepositoryResource CustomRepository 80 | { 81 | Ensure = 'present' 82 | Name = 'MyCustomRepositoryName' 83 | PublishLocation = 'http://www.somelocation/publish' 84 | SourceLocation = 'http://www.somelocation/src' 85 | } 86 | PSModuleResource AzureExt 87 | { 88 | Ensure = 'present' 89 | Module_Name = 'AzureExt' 90 | Repository = 'MyCustomRepositoryName' 91 | DependsOn = @('[PSModuleRepositoryResource]CustomRepository') 92 | } 93 | ```` 94 | 95 | Using AllowClobber 96 | ````powershell 97 | PSModuleResource AzureExt 98 | { 99 | Ensure = 'present' 100 | Module_Name = 'AzureExt' 101 | AllowClobber = $true 102 | } 103 | ```` 104 | 105 | ## More Info: 106 | Read https://david-obrien.net/2015/09/powershell-dsc-to-manage-powershell-modules/ 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DscResources 2 | This repository will contain custom PowerShell DSC Resources 3 | --------------------------------------------------------------------------------