Skip to content

Commit e63226b

Browse files
pl4ntyclaude
andcommitted
Add -PerUser support to Register-ADTDll, Unregister-ADTDll and Invoke-ADTRegSvr32.
Adds a -PerUser switch that performs per-user DLL registration via regsvr32.exe /n /i:user, calling the DLL's DllInstall entry point so registration data is written to HKCU instead of HKLM. When invoked under the SYSTEM account, regsvr32.exe is executed in the context of the currently logged on user via Start-ADTProcessAsUser so the registration lands in the correct user hive. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent dff8573 commit e63226b

3 files changed

Lines changed: 59 additions & 7 deletions

File tree

src/PSAppDeployToolkit/Public/Invoke-ADTRegSvr32.ps1

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ function Invoke-ADTRegSvr32
1919
.PARAMETER Action
2020
Specify whether to register or unregister the DLL.
2121
22+
.PARAMETER PerUser
23+
Specifies that the DLL should be registered for the current user only by calling its DllInstall entry point with the 'user' argument (regsvr32.exe /n /i:user). If this function is running under the SYSTEM account, regsvr32.exe is executed in the context of the currently logged on user. Note that the DLL must support per-user registration via a DllInstall export for this to work.
24+
2225
.INPUTS
2326
None
2427
@@ -39,6 +42,11 @@ function Invoke-ADTRegSvr32
3942
4043
Unregisters the specified DLL file.
4144
45+
.EXAMPLE
46+
Invoke-ADTRegSvr32 -FilePath "C:\Test\DcTLSFileToDMSComp.dll" -Action 'Register' -PerUser
47+
48+
Registers the specified DLL file for the currently logged on user only.
49+
4250
.NOTES
4351
An active ADT session is NOT required to use this function.
4452
@@ -72,7 +80,10 @@ function Invoke-ADTRegSvr32
7280

7381
[Parameter(Mandatory = $true)]
7482
[ValidateSet('Register', 'Unregister')]
75-
[System.String]$Action
83+
[System.String]$Action,
84+
85+
[Parameter(Mandatory = $false)]
86+
[System.Management.Automation.SwitchParameter]$PerUser
7687
)
7788

7889
begin
@@ -83,12 +94,12 @@ function Invoke-ADTRegSvr32
8394
{
8495
Register
8596
{
86-
"/s `"$FilePath`""
97+
"/s$(if ($PerUser) { ' /n /i:user' }) `"$FilePath`""
8798
break
8899
}
89100
Unregister
90101
{
91-
"/s /u `"$FilePath`""
102+
"/s /u$(if ($PerUser) { ' /n /i:user' }) `"$FilePath`""
92103
break
93104
}
94105
}
@@ -153,8 +164,27 @@ function Invoke-ADTRegSvr32
153164
throw (New-ADTErrorRecord @naerParams)
154165
}
155166

156-
# Register the DLL file and measure the success.
157-
Start-ADTProcess -FilePath $RegSvr32Path -ArgumentList $ActionParameters -CreateNoWindow -SuccessExitCodes 0
167+
# Register the DLL file and measure the success. Per-user registration writes to the
168+
# user's HKCU hive, so when running as SYSTEM, execute as the logged on user instead.
169+
if ($PerUser -and [PSADT.AccountManagement.AccountUtilities]::CallerSid.IsWellKnown([System.Security.Principal.WellKnownSidType]::LocalSystemSid))
170+
{
171+
if (!(Get-ADTClientServerUser))
172+
{
173+
$naerParams = @{
174+
Exception = [System.InvalidOperationException]::new("The DLL file [$FilePath] cannot be $($Action.ToLowerInvariant() + 'ed') per-user as there is no logged on user to process the request against.")
175+
Category = [System.Management.Automation.ErrorCategory]::InvalidOperation
176+
ErrorId = 'NoActiveUserError'
177+
TargetObject = $FilePath
178+
RecommendedAction = "Please ensure a user is logged onto the system and try again."
179+
}
180+
throw (New-ADTErrorRecord @naerParams)
181+
}
182+
Start-ADTProcessAsUser -FilePath $RegSvr32Path -ArgumentList $ActionParameters -CreateNoWindow -SuccessExitCodes 0
183+
}
184+
else
185+
{
186+
Start-ADTProcess -FilePath $RegSvr32Path -ArgumentList $ActionParameters -CreateNoWindow -SuccessExitCodes 0
187+
}
158188
}
159189
catch
160190
{

src/PSAppDeployToolkit/Public/Register-ADTDll.ps1

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ function Register-ADTDll
1616
.PARAMETER FilePath
1717
Path to the DLL file.
1818
19+
.PARAMETER PerUser
20+
Specifies that the DLL should be registered for the current user only by calling its DllInstall entry point with the 'user' argument (regsvr32.exe /n /i:user). If this function is running under the SYSTEM account, regsvr32.exe is executed in the context of the currently logged on user. Note that the DLL must support per-user registration via a DllInstall export for this to work.
21+
1922
.INPUTS
2023
None
2124
@@ -31,6 +34,11 @@ function Register-ADTDll
3134
3235
Registers the specified DLL file.
3336
37+
.EXAMPLE
38+
Register-ADTDll -FilePath "C:\Test\DcTLSFileToDMSComp.dll" -PerUser
39+
40+
Registers the specified DLL file for the currently logged on user only.
41+
3442
.NOTES
3543
An active ADT session is NOT required to use this function.
3644
@@ -59,7 +67,10 @@ function Register-ADTDll
5967
}
6068
return ![System.String]::IsNullOrWhiteSpace($_)
6169
})]
62-
[System.String]$FilePath
70+
[System.String]$FilePath,
71+
72+
[Parameter(Mandatory = $false)]
73+
[System.Management.Automation.SwitchParameter]$PerUser
6374
)
6475

6576
begin

src/PSAppDeployToolkit/Public/Unregister-ADTDll.ps1

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ function Unregister-ADTDll
1616
.PARAMETER FilePath
1717
Path to the DLL file.
1818
19+
.PARAMETER PerUser
20+
Specifies that the DLL should be unregistered for the current user only by calling its DllInstall entry point with the 'user' argument (regsvr32.exe /u /n /i:user). If this function is running under the SYSTEM account, regsvr32.exe is executed in the context of the currently logged on user. Note that the DLL must support per-user registration via a DllInstall export for this to work.
21+
1922
.INPUTS
2023
None
2124
@@ -31,6 +34,11 @@ function Unregister-ADTDll
3134
3235
Unregisters the specified DLL file.
3336
37+
.EXAMPLE
38+
Unregister-ADTDll -FilePath "C:\Test\DcTLSFileToDMSComp.dll" -PerUser
39+
40+
Unregisters the specified DLL file for the currently logged on user only.
41+
3442
.NOTES
3543
An active ADT session is NOT required to use this function.
3644
@@ -59,7 +67,10 @@ function Unregister-ADTDll
5967
}
6068
return ![System.String]::IsNullOrWhiteSpace($_)
6169
})]
62-
[System.String]$FilePath
70+
[System.String]$FilePath,
71+
72+
[Parameter(Mandatory = $false)]
73+
[System.Management.Automation.SwitchParameter]$PerUser
6374
)
6475

6576
begin

0 commit comments

Comments
 (0)