nekku6
Goto Top

Bitlocker recovery key delegation via Powershell

Hello admins!

In the A better way to delegate control for Bitlocker recovery keys post by @DerWoWusste we've been introduced by the approach that allows to avoid delegating full control to IT Techs who are supposed to be able to find bitocker recovery keys.

I have a question regarding implementation of the same thing but in Powershell.
I work in the education organization that supports 140 schools. One of the MSPs that we're working with services 83 of them.
I need to delegate their (MSP) IT Tech AD group a bitlocker keys read permissions in their corresponding OUs (domain/Resources/<SchoolCode>/Windows Computers)
The closest I found was in TechNet's post that the OP was complaining about as not working.

dsacls.exe "OU=Computers,$OrganizationalUnitDN" /G $prefixlocation-$type":RP;msFVE-RecoveryPassword;msFVE-RecoveryInformation" /I:S  

I have some PS experience in ExchangeOnline (link leads to SpiceWorks O365 related question of mine that I answer myself), but I'm not sure what to start with in this case.
Please nudge me in the right direction.

Content-ID: 1638502270

Url: https://administrator.de/contentid/1638502270

Ausgedruckt am: 26.11.2024 um 04:11 Uhr

DerWoWusste
DerWoWusste 20.12.2021 um 09:42:25 Uhr
Goto Top
Hi.

The confidentiality bit is set using the control access parameter CA.
DSACLS "OU=Test,OU=computers,DC=dom,DC=local" /I:S /G "mydom\helpdesk:CA"
However, testing that, I did not succeed to limit this control access to certain attributes only.
colinardo
Lösung colinardo 20.12.2021 aktualisiert um 16:18:34 Uhr
Goto Top
Hi @nekku6, welcome to administrator.pro!

If you want create the delegation with pure powershell you can do it like this. This will grant read access, sets the confidentially bit on subordinate msFVE-RecoveryInformation objects for a defined OU and user/group.

<#
    Delegate read access to Bitlocker-RecoveryInformation objects in AD Organizational Units
#>
Import-Module ActiveDirectory
# OU
$OU = 'OU=MyAdmins,DC=testlab,dc=intern'  
# Group/Account
$account = ([System.Security.Principal.NTAccount]"MyAdminGroup")  
# get acl of the OU
$acl = Get-ACL "AD:$OU"     
# create the access rule
$rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($account,'ReadProperty,ExtendedRight','Allow','{00000000-0000-0000-0000-000000000000}','All',"{ea715d30-8f53-40d0-bd1e-6109186d782c}")  
# add the rule to acl
$acl.AddAccessRule($rule)
# save acl back to the OU
Set-ACL "AD:$OU" $acl  

As @DerWoWusste already mentioned, restricting the extended right for only the attribute msFVE-RecoveryPassword is not possible, it must be delegated to the whole msFVE-RecoveryInformation object .

Regards @colinardo
DerWoWusste
DerWoWusste 20.12.2021 um 14:42:41 Uhr
Goto Top
Great.
I could confirm this to be working!
nekku6
nekku6 21.12.2021 aktualisiert um 03:13:27 Uhr
Goto Top
Hi @colinardo,
Thank you, that worked for me! It gives all sorts of those additional reading rights, but it should be fine.
Although, I still have a quick question for you on how did you find the IDs used in the rule creation. I assume there should be something describing that on docs.ms like they have for exchange cmdlets' switches, but I'm not sure what to ask for to look it up.

And thank you @DerWoWusste for inspiring me to keep investigating and introducing to this site!

BTW, it took less than 2 seconds compared to what I'd imagine be a tedious whole day clicking face-smile
Script started at 12/21/2021 11:24:57
Script completed at 12/21/2021 11:24:59
Script took 00:00:01.9687952 to complete
Just in case anyone who's new to PS reads the article and maybe finds this useful, here's my foreach modification for this script.
#Import-Module ActiveDirectory

$Import = Import-Csv d:\temp\INC\NF-BL-import.csv
$LIF = $Import | Measure-Object
$LIFC = $LIF.count
Write-host "$LIFC lines in file" -ForegroundColor Yellow  

$RL = 0
$ScriptStartTime = Get-Date
Write-Host "Script started at $ScriptStartTime"  

foreach ($Line in $Import) { 
    ### Defining OU from the import ###
    $Group = ([System.Security.Principal.NTAccount]$Line.Group)
    ### Defining OU from the import ###
    $ACL = Get-ACL "AD:$($Line.DN)"  
    ### Creating the access rule ###
    $Rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($Group,'ReadProperty,ExtendedRight','Allow','{00000000-0000-0000-0000-000000000000}','All',"{ea715d30-8f53-40d0-bd1e-6109186d782c}")  
    ### Adding created rule to ACL ###
    $ACL.AddAccessRule($Rule)
    ### Setting the rule for the defined OU ###
    Set-ACL "AD:$($Line.DN)" $ACL  

    Write-Host "Progress: $($Line.DN) has been delegated to $($Line.Group)" -ForegroundColor Yellow  
    $RL++
    Write-Host "Progress: $RL of $LIFC" -ForegroundColor Yellow  
}

$ScriptEndTime = Get-Date
$TTR = $ScriptEndTime - $ScriptStartTime
Write-Host "Script started at $ScriptStartTime"  
Write-Host "Script completed at $ScriptEndTime"  
Write-Host "Script took $TTR to complete" -ForegroundColor Green  
colinardo
colinardo 21.12.2021 aktualisiert um 07:44:56 Uhr
Goto Top
You can find the GUIDs easly in your AD Schema, for example, for the attributes
Get-ADObject -Searchbase (Get-ADRootDSE).schemaNamingContext -Filter {objectClass -eq 'attributeSchema'}  
Or via GUI by opening adsiedit.msc, and connecting to your schema context.