Skip to content

Commit 7461b40

Browse files
Add Registry Key and Entry Commands
1 parent cd9dcea commit 7461b40

File tree

10 files changed

+588
-17
lines changed

10 files changed

+588
-17
lines changed

.build

README.md

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,52 @@
1-
# Be.Stateless.PowerShell.Module.Psx
1+
# Psx PowerShell Module
22

3-
[![Build Status](https://dev.azure.com/icraftsoftware/be.stateless/_apis/build/status/Be.Stateless.PowerShell.Module.Psx%20Manual%20Release?branchName=master)](https://dev.azure.com/icraftsoftware/be.stateless/_build/latest?definitionId=22&branchName=master)
4-
[![GitHub Release](https://img.shields.io/github/v/release/icraftsoftware/Be.Stateless.PowerShell.Module.Psx?label=Release&logo=github)](https://github.com/icraftsoftware/Be.Stateless.PowerShell.Module.Psx/releases/latest)
5-
[![PowerShell Gallery Version](https://img.shields.io/powershellgallery/v/Psx.svg?style=flat&logo=powershell)](https://www.powershellgallery.com/packages/Psx)
3+
`Psx` is a scaffolding `PowerShell` utility module.
64

7-
Utility PowerShell functions and commands.
5+
## Status
86

9-
## Module Installation
7+
<!-- pipeline ci whatever branch build passing -->
108

11-
Notice that to be able to install this PowerShell module right from the PowerShell Gallery you will need to trust the certificate that was used to sign it. Run the following PowerShell commands (they merely download and install the certificate's public key in the 'Trusted People' store underneath the 'Local Machine' certificate store):
9+
[![][pipeline.ci.badge]][pipeline.ci]
1210

13-
```PowerShell
14-
Invoke-WebRequest -Uri https://github.com/icraftsoftware/Be.Stateless.Build.Scripts/raw/master/be.stateless.public.cer -OutFile "$($env:TEMP)\be.stateless.public.cer"
15-
Import-Certificate -FilePath "$($env:TEMP)\be.stateless.public.cer" -CertStoreLocation Cert:\LocalMachine\TrustedPeople\
16-
```
11+
[![][pipeline.mr.badge]][pipeline.mr]
1712

18-
Notice that if the `ExecutionPolicy` is set to `AllSigned` you also need to run the following PowerShell command (it merely installs the certificate's public key in the 'Trusted Publishers' store underneath the 'Local Machine' certificate store):
13+
## Latest Release
1914

20-
```PowerShell
21-
Import-Certificate -FilePath "$($env:TEMP)\be.stateless.public.cer" -CertStoreLocation Cert:\LocalMachine\TrustedPublisher\
22-
```
15+
<!-- build passing (mr pipeline) -->
16+
17+
[![][module.badge]][module]
18+
19+
[![][release.badge]][release]
20+
21+
## Release Preview
22+
23+
<!-- build passing (ci on master pipeline) -->
24+
25+
[![][module.preview.badge]][module.preview]
26+
27+
## Documentation
28+
29+
- [About][doc.this] `Psx`;
30+
- [About][doc.main] `BizTalk.Factory` SDK.
31+
32+
## Installation
33+
34+
- [About][doc.install] `BizTalk.Factory`'s `PowerShell` module installation.
35+
36+
<!-- links -->
37+
38+
[doc.main]: https://www.stateless.be/ "BizTalk.Factory SDK"
39+
[doc.this]: https://www.stateless.be/PowerShell/Module/Psx/ "Psx PowerShell Module"
40+
[doc.install]: https://www.stateless.be/PowerShell/Module/Installation.html "PowerShell Module Installation"
41+
[github]: https://github.com/icraftsoftware/Be.Stateless.PowerShell.Module.Psx "Be.Stateless.PowerShell.Module.Psx GitHub Repository"
42+
[github.badge]: https://img.shields.io/static/v1?label=Repository&message=Be.Stateless.PowerShell.Module.Psx&logo=github
43+
[pipeline.ci]: https://dev.azure.com/icraftsoftware/be.stateless/_build/latest?definitionId=21&branchName=master "Azure DevOps Continuous Integration Build Pipeline"
44+
[pipeline.ci.badge]: https://dev.azure.com/icraftsoftware/be.stateless/_apis/build/status/Be.Stateless.PowerShell.Module.Psx%20Continuous%20Integration?branchName=master&label=Continuous%20Integration%20Build
45+
[pipeline.mr]: https://dev.azure.com/icraftsoftware/be.stateless/_build/latest?definitionId=22&branchName=master "Azure DevOps Release Build Pipeline"
46+
[pipeline.mr.badge]: https://dev.azure.com/icraftsoftware/be.stateless/_apis/build/status/Be.Stateless.PowerShell.Module.Psx%20Manual%20Release?branchName=master&label=Manual%20Release%20Build
47+
[module.preview]: https://dev.azure.com/icraftsoftware/be.stateless/_packaging?_a=package&feed=BizTalk.Factory.Preview&package=Psx&protocolType=NuGet "Psx PowerShell Module Preview"
48+
[module.preview.badge]: https://badge-factory.azurewebsites.net/package/icraftsoftware/be.stateless/BizTalk.Factory.Preview/Psx?logo=powershell
49+
[module]: https://www.powershellgallery.com/packages/Psx "Psx PowerShell Module"
50+
[module.badge]: https://img.shields.io/powershellgallery/v/Psx.svg?label=Psx&style=flat&logo=powershell
51+
[release]: https://github.com/icraftsoftware/Be.Stateless.PowerShell.Module.Psx/releases/latest "Be.Stateless.PowerShell.Module.Psx GitHub Release"
52+
[release.badge]: https://img.shields.io/github/v/release/icraftsoftware/Be.Stateless.PowerShell.Module.Psx?label=Release&logo=github

src/Psx/Psx.psd1

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@
5151
# Pipeline.ps1
5252
'Test-Any',
5353
'Test-None',
54+
# Registry.ps1
55+
'Clear-RegistryKey',
56+
'Get-RegistryEntry',
57+
'Remove-RegistryEntry',
58+
'Set-RegistryEntry',
59+
'Test-RegistryEntry',
5460
# ScriptBlock.ps1
5561
'Convert-ScriptBlockParametersToDynamicParameters',
5662
'Invoke-ScriptBlock',
@@ -61,7 +67,7 @@
6167
VariablesToExport = @()
6268
PrivateData = @{
6369
PSData = @{
64-
Tags = @('be.stateless.be', 'icraftsoftware', 'Alias', 'HashTable', 'Pipeline', 'PowerShell', 'Utilities', 'UAC')
70+
Tags = @('be.stateless', 'icraftsoftware', 'Alias', 'HashTable', 'Pipeline', 'PowerShell', 'Utilities', 'UAC')
6571
LicenseUri = 'https://github.com/icraftsoftware/Be.Stateless.PowerShell.Module.Psx/blob/master/LICENSE'
6672
ProjectUri = 'https://github.com/icraftsoftware/Be.Stateless.PowerShell.Module.Psx'
6773
Prerelease = 'preview'

src/Psx/Psx.psm1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ Set-StrictMode -Version Latest
2525
. $PSScriptRoot\HashTable\HashTable.ps1
2626
. $PSScriptRoot\Object\Object.ps1
2727
. $PSScriptRoot\Pipeline\Pipeline.ps1
28+
. $PSScriptRoot\Registry\Registry.ps1
2829
. $PSScriptRoot\ScriptBlock\ScriptBlock.ps1
2930
. $PSScriptRoot\Uac\Uac.ps1

src/Psx/Registry/Registry.ps1

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
#region Copyright & License
2+
3+
# Copyright © 2012 - 2022 François Chabot
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
#endregion
18+
19+
Set-StrictMode -Version Latest
20+
21+
<#
22+
.SYNOPSIS
23+
Deletes a registry key if it is empty and, if the Recurse switch is used, recursively deletes all its empty ancestor keys, up to but not including the root key.
24+
.DESCRIPTION
25+
This command deletes a registry key if it is empty and, if the Recurse switch is used, recursively deletes all its empty ancestor keys, up to but not including the
26+
root key.
27+
.PARAMETER Key
28+
The name or path of the key.
29+
.PARAMETER Recurse
30+
Whether to delete this key's empty ancestors as well.
31+
.EXAMPLE
32+
PS> Clear-RegistryKey -Key HKLM:\SOFTWARE\BizTalk.Factory\BizTalk.Deployment\InstalledManifests
33+
.EXAMPLE
34+
PS> Clear-RegistryKey -Key HKLM:\SOFTWARE\BizTalk.Factory\BizTalk.Deployment\InstalledManifests -Recurse
35+
.NOTES
36+
© 2022 be.stateless.
37+
#>
38+
function Clear-RegistryKey {
39+
[CmdletBinding()]
40+
[OutputType([void])]
41+
param(
42+
[Parameter(Mandatory = $true)]
43+
[string]
44+
$Key,
45+
46+
[Parameter(Mandatory = $false)]
47+
[switch]
48+
$Recurse
49+
)
50+
Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
51+
# proceeds while this key's parent has a parent and this parent's parent is not the drive, i.e. while not a root path, e.g. HKLM:\SOFTWARE, nor a drive, e.g. HKLM:\
52+
if ((Test-Path -Path $Key) -and ($i = Get-Item -Path $Key).PSParentPath -and (Get-Item -Path $i.PSParentPath).Name -ne $i.PSDrive.Root) {
53+
if ((Get-ChildItem -Path $Key | Test-None) -and (Get-ItemProperty -Path $Key | Test-None)) {
54+
Write-Verbose -Message "Registry clearing removed empty key '$Key'."
55+
Remove-Item -Path $Key
56+
if ($Recurse) {
57+
Clear-RegistryKey -Key (Split-Path -Path $Key -Parent) -Recurse
58+
}
59+
} else {
60+
Write-Verbose -Message "Registry clearing skipped non empty key '$Key'."
61+
}
62+
}
63+
}
64+
65+
<#
66+
.SYNOPSIS
67+
Gets the value of one entry under a specified registry key.
68+
.DESCRIPTION
69+
This command gets the current value of a given entry located under a given registry key. It does not fail like the Get-ItemPropertyValue command if the key or entry
70+
does not exist and returns $null instead.
71+
.PARAMETER Key
72+
The name or path of the key.
73+
.PARAMETER Entry
74+
The name of the entry.
75+
.EXAMPLE
76+
PS> Get-RegistryEntry -Key HKLM:\SOFTWARE\BizTalk.Factory\BizTalk.Deployment\InstalledManifests -Entry $Manifest.Properties.Name
77+
.NOTES
78+
© 2022 be.stateless.
79+
#>
80+
function Get-RegistryEntry {
81+
[CmdletBinding()]
82+
[OutputType([object])]
83+
param(
84+
[Parameter(Position = 0, Mandatory = $true)]
85+
[ValidateNotNullOrEmpty()]
86+
[string]
87+
$Key,
88+
89+
[Parameter(Position = 1, Mandatory = $true)]
90+
[ValidateNotNullOrEmpty()]
91+
[string]
92+
$Entry
93+
)
94+
Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
95+
if (Test-RegistryEntry -Key $Key -Entry $Entry) {
96+
Get-ItemPropertyValue -Path $Key -Name $Entry
97+
}
98+
}
99+
100+
<#
101+
.SYNOPSIS
102+
Deletes an entry under a registry key.
103+
.DESCRIPTION
104+
This command deletes an entry under a registry key.
105+
.PARAMETER Key
106+
The name or path of the key.
107+
.PARAMETER Entry
108+
The name of the entry.
109+
.EXAMPLE
110+
PS> Remove-RegistryEntry -Key HKLM:\SOFTWARE\BizTalk.Factory\BizTalk.Deployment\InstalledManifests -Entry $Manifest.Properties.Name
111+
.NOTES
112+
© 2022 be.stateless.
113+
#>
114+
function Remove-RegistryEntry {
115+
[CmdletBinding()]
116+
[OutputType([void])]
117+
param(
118+
[Parameter(Position = 0, Mandatory = $true)]
119+
[ValidateNotNullOrEmpty()]
120+
[string]
121+
$Key,
122+
123+
[Parameter(Position = 1, Mandatory = $true)]
124+
[ValidateNotNullOrEmpty()]
125+
[string]
126+
$Entry
127+
)
128+
Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
129+
if (Test-RegistryEntry -Key $Key -Entry $Entry) {
130+
Remove-ItemProperty -Path $Key -Name $Entry
131+
}
132+
}
133+
134+
<#
135+
.SYNOPSIS
136+
Creates or changes the value of an entry under a registry key.
137+
.DESCRIPTION
138+
This command creates or changes the value of an entry under a registry key. This commands can also create a new key if it does not exist and the Force switch is
139+
used.
140+
.PARAMETER Key
141+
The name or path of the key to create or open.
142+
.PARAMETER Entry
143+
The name of the entry.
144+
.PARAMETER Value
145+
The data to be stored.
146+
.PARAMETER Type
147+
The registry data type to use when storing the data. The acceptable values for this parameter are:
148+
- Binary: Specifies binary data in any form. Used for REG_BINARY values.
149+
- DWord: Specifies a 32-bit binary number. Used for REG_DWORD values.
150+
- QWord: Specifies a 64-bit binary number. Used for REG_QWORD values.
151+
- String: Specifies a null-terminated string. Used for REG_SZ values.
152+
- MultiString: Specifies an array of null-terminated strings terminated by two null characters. Used for REG_MULTI_SZ values.
153+
- ExpandString: Specifies a null-terminated string that contains unexpanded references to environment variables that are expanded when the value is retrieved.
154+
Used for REG_EXPAND_SZ values.
155+
- Unknown: Indicates an unsupported registry data type, such as REG_RESOURCE_LIST values.
156+
.PARAMETER Force
157+
Whether to create a new registry key if it does not exist.
158+
.EXAMPLE
159+
PS> Set-RegistryEntry -Key HKLM:\SOFTWARE\BizTalk.Factory\BizTalk.Deployment\InstalledManifests -Entry $Manifest.Properties.Name -Value $Manifest.Properties.Path
160+
.EXAMPLE
161+
PS> Set-RegistryEntry -Key HKLM:\SOFTWARE\Key -Entry name -Value 12 -Type DWord -Force
162+
.NOTES
163+
© 2022 be.stateless.
164+
#>
165+
function Set-RegistryEntry {
166+
[CmdletBinding()]
167+
[OutputType([void])]
168+
param(
169+
[Parameter(Position = 0, Mandatory = $true)]
170+
[ValidateNotNullOrEmpty()]
171+
[string]
172+
$Key,
173+
174+
[Parameter(Position = 1, Mandatory = $true)]
175+
[ValidateNotNullOrEmpty()]
176+
[string]
177+
$Entry,
178+
179+
[Parameter(Position = 2, Mandatory = $true)]
180+
[ValidateNotNullOrEmpty()]
181+
[object]
182+
$Value,
183+
184+
[Parameter(Position = 3, Mandatory = $false)]
185+
[ValidateNotNullOrEmpty()]
186+
[Microsoft.Win32.RegistryValueKind]
187+
$Type,
188+
189+
[Parameter(Mandatory = $false)]
190+
[switch]
191+
$Force
192+
)
193+
Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
194+
if (-not(Test-Path -Path $Key) -and $Force) {
195+
New-Item -Path $Key -Force | Out-Null
196+
}
197+
if (Test-RegistryEntry -Key $Key -Entry $Entry) {
198+
Set-ItemProperty -Path $Key -Name $Entry -Value $Value
199+
} else {
200+
New-ItemProperty -Path $Key -Name $Entry -Value $Value -PropertyType $Type | Out-Null
201+
}
202+
}
203+
204+
205+
<#
206+
.SYNOPSIS
207+
Determines if an entry under a registry key exists.
208+
.DESCRIPTION
209+
This command determines if an entry under a registry key exists. It returns $True if the key exists and contains the entry. It returns $False otherwise.
210+
.PARAMETER Key
211+
The name or path of the key.
212+
.PARAMETER Entry
213+
The name of the entry.
214+
.EXAMPLE
215+
PS> Test-RegistryEntry -Key HKLM:\SOFTWARE\BizTalk.Factory\BizTalk.Deployment\InstalledManifests -Entry $Manifest.Properties.Name
216+
.NOTES
217+
© 2022 be.stateless.
218+
#>
219+
function Test-RegistryEntry {
220+
[CmdletBinding()]
221+
[OutputType([bool])]
222+
param(
223+
[Parameter(Position = 0, Mandatory = $true)]
224+
[ValidateNotNullOrEmpty()]
225+
[string]
226+
$Key,
227+
228+
[Parameter(Position = 1, Mandatory = $true)]
229+
[ValidateNotNullOrEmpty()]
230+
[string]
231+
$Entry
232+
)
233+
Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
234+
[bool]((Test-Path -Path $Key) -and (Get-Item -Path $Key | Where-Object -Property Property -Contains $Entry))
235+
}

0 commit comments

Comments
 (0)