Skip to content

Commit 165cc35

Browse files
committed
Add Script for Intune SMIME upload
1 parent 71bc82c commit 165cc35

File tree

2 files changed

+415
-161
lines changed

2 files changed

+415
-161
lines changed

Push-SmimeCertificatesToIntune.ps1

+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
<#
2+
3+
.SYNOPSIS
4+
5+
.Parameter ConfigString
6+
7+
.Parameter CertificateTemplates
8+
9+
.Parameter UserName
10+
11+
.Parameter RequestId
12+
13+
.Parameter PfxEncryptionKeyName
14+
15+
#>
16+
17+
#Requires -Modules IntunePfxImport, ActiveDirectory
18+
19+
[cmdletbinding()]
20+
param(
21+
[Parameter(Mandatory = $False)]
22+
[ValidateNotNullOrEmpty()]
23+
[String]
24+
$ConfigString = "ca02.intra.adcslabor.de\ADCS Labor Issuing CA 1",
25+
26+
[Parameter(Mandatory=$False)]
27+
[ValidateNotNullOrEmpty()]
28+
[String[]]
29+
$CertificateTemplates = @(
30+
"1.3.6.1.4.1.311.21.8.6301991.2938543.412570.1725121.735828.231.4136173.9322655" # Some S/MIME Certificate Template
31+
),
32+
33+
[Parameter(Mandatory=$False)]
34+
[ValidateNotNullOrEmpty()]
35+
[String]
36+
$UserName,
37+
38+
[Parameter(Mandatory=$False)]
39+
[ValidateNotNullOrEmpty()]
40+
[Int]
41+
$RequestId,
42+
43+
[Parameter(Mandatory=$False)]
44+
[ValidateNotNullOrEmpty()]
45+
[String]
46+
$PfxEncryptionKeyName = "PFXEncryptionKey"
47+
)
48+
49+
# Ensuring the Script will be run with Elevation
50+
If (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
51+
Write-Error -Message "This must be run as Administrator! Aborting."
52+
Return
53+
}
54+
55+
. $(Split-Path -Path $MyInvocation.MyCommand.Definition -Parent)\lib\Get-CADatabaseRecord.ps1
56+
57+
New-Variable -Option Constant -Name XCN_CRYPT_STRING_BASE64 -Value 1
58+
New-Variable -Option Constant -Name szOID_KEY_USAGE -Value "2.5.29.15"
59+
New-Variable -Option Constant -Name szOID_ENHANCED_KEY_USAGE -Value "2.5.29.37"
60+
New-Variable -Option Constant -Name szOID_KP_KEY_RECOVERY_AGENT -Value "1.3.6.1.4.1.311.21.6"
61+
New-Variable -Option Constant -Name szOID_PKIX_KP_EMAIL_PROTECTION -Value "1.3.6.1.5.5.7.3.4"
62+
63+
Add-Type -AssemblyName 'System.Web'
64+
65+
$AllKraCertificates = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object { $_.Extensions |
66+
Where-Object { $_.Oid.Value -eq $szOID_ENHANCED_KEY_USAGE } |
67+
Where-Object { $_.EnhancedKeyUsages.Value -eq $szOID_KP_KEY_RECOVERY_AGENT }
68+
}
69+
70+
$CertAdmin = New-Object -ComObject CertificateAuthority.Admin
71+
72+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
73+
74+
Set-IntuneAuthenticationToken
75+
76+
foreach ($CertificateTemplate in $CertificateTemplates) {
77+
78+
$Arguments = @{
79+
ConfigString = $ConfigString
80+
CertificateTemplate = $CertificateTemplate
81+
HasArchivedKeys = $True
82+
Properties = "RequestId","SerialNumber","UPN","Request.RequesterName","CertificateHash"
83+
}
84+
85+
If ($UserName) { $Arguments.Add("RequesterName", $UserName) }
86+
If ($RequestId) { $Arguments.Add("RequestId", $RequestId) }
87+
88+
foreach ($Result in (Get-CADatabaseRecord @Arguments)) {
89+
90+
$RawCertificate = $CertAdmin.GetArchivedKey($ConfigString, $Result.RequestID, $XCN_CRYPT_STRING_BASE64)
91+
92+
$CertificateCollection = New-Object Security.Cryptography.X509Certificates.X509Certificate2Collection
93+
94+
[void]$CertificateCollection.Import(
95+
[Convert]::FromBase64String($RawCertificate),
96+
$null,
97+
[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet" -band [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"Exportable"
98+
)
99+
100+
$CurrentSmimeCertificate = $CertificateCollection | Where-Object { $_.Extensions |
101+
Where-Object { $_.Oid.Value -eq $szOID_ENHANCED_KEY_USAGE } |
102+
Where-Object { $_.EnhancedKeyUsages.Value -eq $szOID_PKIX_KP_EMAIL_PROTECTION }
103+
}
104+
105+
$KeyUsages = ($CurrentSmimeCertificate | ForEach-Object { $_.Extensions | Where-Object { $_.Oid.Value -eq $szOID_KEY_USAGE } }).KeyUsages
106+
107+
$KraCertificates = ($CertificateCollection | Where-Object { $_.Extensions |
108+
Where-Object { $_.Oid.Value -eq $szOID_ENHANCED_KEY_USAGE } |
109+
Where-Object { $_.EnhancedKeyUsages.Value -eq $szOID_KP_KEY_RECOVERY_AGENT }
110+
}).SerialNumber
111+
112+
If (-not $AllKraCertificates | Where-Object { $KraCertificates -contains $_.SerialNumber -and $_.HasPrivateKey -eq $True }) {
113+
Write-Warning -Message "No KRA Certificate found for certificate with RequestId $($Result.RequestId)."
114+
continue
115+
}
116+
117+
$TempFileName = "$env:Temp\$($Result.SerialNumber).p7b"
118+
$ExportFileName = $TempFileName.Replace(".p7b", ".pfx")
119+
$Password = [System.Web.Security.Membership]::GeneratePassword(16, 4)
120+
121+
Set-Content -Path $TempFileName -Value $RawCertificate -Encoding Ascii
122+
123+
[void] (& certutil -p $Password -f -recoverkey $TempFileName $ExportFileName)
124+
125+
If ($LASTEXITCODE -ne 0) {
126+
Write-Warning -Message "Unable to recover certificate with RequestId $($Result.RequestId)."
127+
continue
128+
}
129+
130+
$UserPrincipalName = (Get-AdUser -Identity ($Result."Request.RequesterName").split("\")[1]).UserPrincipalName
131+
132+
$IntuneUserCertificates = Get-IntuneUserPfxCertificate -UserList $UserPrincipalName
133+
134+
If (($null -ne $IntuneUserCertificates) -and ($IntuneUserCertificates.Thumbprint.ToUpper() -eq $Result.CertificateHash.Replace(" ", "").ToUpper())) {
135+
Write-Warning -Message "Certificate with RequestId $($Result.RequestId) has already been uploaded to Intune."
136+
continue
137+
}
138+
139+
switch ($KeyUsages) {
140+
"KeyEncipherment" { $Purpose = "SmimeEncryption" }
141+
"DigitalSignature" { $Purpose = "SmimeSigning" }
142+
default { $Purpose = "unassigned" }
143+
}
144+
145+
$SecureFilePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
146+
147+
$UserPfxObject = New-IntuneUserPfxCertificate `
148+
-PathToPfxFile $ExportFileName `
149+
-PfxPassword $SecureFilePassword `
150+
-UPN $UserPrincipalName `
151+
-ProviderName "Microsoft Software Key Storage Provider" `
152+
-KeyName $PfxEncryptionKeyName `
153+
-IntendedPurpose $Purpose
154+
155+
try {
156+
Import-IntuneUserPfxCertificate -CertificateList $UserPfxObject
157+
}
158+
catch {
159+
# HTTP 400 error occur in several cases
160+
Write-Warning -Message "Unable to upload certificate with RequestId $($Result.RequestId) to Intune."
161+
}
162+
163+
Remove-Item -Path $ExportFileName -Force
164+
Remove-Item -Path $TempFileName -Force
165+
}
166+
}
167+
168+
Remove-IntuneAuthenticationToken
169+
[void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($CertAdmin))

0 commit comments

Comments
 (0)