New-DbaComputerCertificate - Leave nothing behind on the computer it runs on - #10735
andreasjordan wants to merge 5 commits into
Conversation
…runs on certreq installs a self-signed certificate a second time, without its key, in LocalMachine\CA, and that copy stayed after the certificate was removed. A request the CA did not answer stayed in LocalMachine\REQUEST with its key. A certificate created for another computer was removed from the local store after the export, but its private key file stayed on the source computer. All three are removed now, the last two through Remove-DbaComputerCertificate -DeleteKey. (do New-DbaComputerCertificate) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(do New-DbaComputerCertificate) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…gs of the failed request (do New-DbaComputerCertificate) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…equest reports instead of showing a dialog Without -q certreq shows a modal "Certificate Request Processor" dialog when a submission is refused or the CA cannot be reached, as soon as the session has a window station, and the command waits for someone to click it away. The cleanup of the request folder also passed its message to Stop-Function positionally, which threw instead of warning. (do New-DbaComputerCertificate) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
d81af05 to
ca14220
Compare
potatoqualitee
left a comment
There was a problem hiding this comment.
Blocking: restrict REQUEST-store cleanup to the request created by this invocation (public/New-DbaComputerCertificate.ps1, lines 506-517).
The snapshot at line 463 records every pre-existing request, but the failure path later treats every request created after that snapshot as its own and calls Remove-DbaComputerCertificate -Folder REQUEST -DeleteKey for each one. That selection is based on timing, not ownership.
Concrete failure: invocation A takes the snapshot and waits in certreq -submit; another enrollment process B creates an unrelated machine request; A's submission then fails. A selects both new thumbprints and removes B's request and its unique private key. The helper's shared-key safeguard cannot protect an ordinary unique request, so B can no longer accept or use its eventual certificate. I independently confirmed the exact-head selection and that -DeleteKey reaches the helper's key-deletion path when no other certificate shares the key.
Please identify this invocation's request directly (for example by matching the generated CSR's public key or a uniquely assigned key container) and delete only that request. Add real-boundary coverage proving that an unrelated request created during the submission remains in LocalMachine\REQUEST with its key intact.
…does not answer (do New-DbaComputerCertificate) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Fixed in 2558430. The snapshot is gone. On failure the command reads the CSR it generated itself and removes only the This text was created by Claude and reviewed by Andreas Jordan. |
Why
New-DbaComputerCertificateleaves three things behind on the computer it runs on:certreq -newwithRequestType = Certinstalls a self-signed certificate twice: with its key inLocalMachine\My, and without the key inLocalMachine\CA. Nothing needs that copy (a self-signed certificate is its own root, chain building gives the same result with and without it), andRemove-DbaComputerCertificatedoes not know about it. A lab workstation had 17 of them.LocalMachine\REQUESTwith its private key. When the CA cannot be reached or refuses, the command warns and moves on, and the request with its key stays forever. The same workstation had 19 of them.Two smaller defects on the same paths:
certreqwas run without-q, so a refused submission pops a modal "Certificate Request Processor" dialog whenever the session has a window station, and the command waits for someone to click it away (seen in the lab, the same trap as in the CI runner notes). And the cleanup of the request folder passed its message toStop-Functionpositionally, which throws "A positional parameter cannot be found" instead of warning.What changes
LocalMachine\CA.LocalMachine\REQUESTare noted beforecertreq -new; after a refused submission every new one is removed withRemove-DbaComputerCertificate -Folder REQUEST -DeleteKey, and the warning carries the last line of the certreq output instead of an empty$_.-DeleteKey; if the key does not go, the output of that removal is reported as a warning, and the import on the target goes ahead either way.certreqcalls run with-q.Stop-Functioncall for the request folder gets its-Message.Tests
LocalMachine\Myand not inLocalMachine\CA.Set-ItResultwhen the instance runs on this computer, as on CI, where the transfer does not happen.nosuchca.dbatools.invalidwarns with the Stop-Function message, returns nothing, and leavesLocalMachine\REQUESTand the key folders as they were. Its AfterAll removes a request the command might have left.Verification
Lab (ADMIN01, remote target SQL03):
-DeleteKeydoes not exist there.created by Claude and reviewed by Andreas Jordan
🤖 Generated with Claude Code