-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathSync-NewCertPermissions.ps1
78 lines (68 loc) · 2.74 KB
/
Sync-NewCertPermissions.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<#
.SYNOPSIS
Updates permissions on certs when there is an older cert with the same friendly name.
.LINK
https://docs.microsoft.com/dotnet/api/system.security.accesscontrol.filesystemaccessrule
.LINK
Format-Certificate.ps1
.LINK
Get-CertificatePermissions.ps1
.LINK
Get-CertificatePath.ps1
.LINK
Get-Acl
.LINK
Set-Acl
.EXAMPLE
Find-Certificate.ps1 subject.name FindBySubjectName TrustedPeople LocalMachine |Sync-NewCertificatePermissions.ps1
Updates permissions on the newest certificate using the second newest as a template.
#>
#Requires -RunAsAdministrator
#Requires -Version 3
[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')] Param(
# X509Certificate2 to copy permissions between.
[Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromRemainingArguments=$true)]
[System.Security.Cryptography.X509Certificates.X509Certificate2[]] $Certificate
)
Begin
{
filter Select-Relevant
{ # ignore untethered SIDs and inherited perms
try {if($_.IdentityReference.Translate([Security.Principal.NTAccount]).Value -and !$_.IsInherited) {return $_}}
catch {}
}
filter ConvertTo-JsonRule
{
return "[$(($_.IdentityReference.Value |ConvertTo-Json),[int]$_.FileSystemRights,[int]$_.AccessControlType -join ',')]"
}
}
End
{
[System.Security.Cryptography.X509Certificates.X509Certificate2[]] $certs =
if($input) {$input.ForEach({$_})} # flatten nested arrays
else {$Certificate}
$newcert, $prevcert = $certs.Group |Sort-Object NotAfter -Descending
$newcertname = Format-Certificate.ps1 $newcert
[string[]] $prevperms = @(Get-CertificatePermissions.ps1 $prevcert |Select-Relevant |ConvertTo-JsonRule |Sort-Object)
[string[]] $newperms = @(Get-CertificatePermissions.ps1 $newcert |Select-Relevant |ConvertTo-JsonRule |Sort-Object)
$addperms = @()
$removeperms = @()
foreach ($diff in Compare-Object $prevperms $newperms)
{
$value = ConvertFrom-Json $diff.InputObject
if ($diff.SideIndicator -eq '=>') { $removeperms += New-Object Security.AccessControl.FileSystemAccessRule $value }
else { $addperms += New-Object Security.AccessControl.FileSystemAccessRule $value }
}
if (($addperms.Count -eq 0) -and ($removeperms.Count -eq 0)) { continue }
$newcertpath = Get-CertificatePath.ps1 $newcert
$acl = Get-Acl $newcertpath
foreach ($perm in $addperms)
{
$who, $type, $rights = $perm.IdentityReference.Value, $perm.AccessControlType, $perm.FileSystemRights
if (!$PSCmdlet.ShouldProcess($newcertname, "set $type $rights access for $who")) { continue }
Write-Verbose "Setting $who $type $rights access to $newcertname"
$acl.SetAccessRule($perm)
}
#TODO: remove $removeperms, conditionally after adding switch param $RemoveNewPerms
Set-Acl $newcertpath $acl
}