Security Incident Response

If you think you have or know you have a Security Incident please fill in the form and our experienced Onevinn CSIRT team will reach out shortly.
 
The team has long experience in supporting customers in Incident Response and Compromised Recovery.
 
Keep calm and we will be with you shortly!

Jörgen Nilsson 24 Sep 2019
4 min

Configuring Dell BIOS Settings using Intune Win32App and PowerShell

By my Padawan and co-worker Sassan.
This is a quick post about the possibility to manage and configure some BIOS settings on Dell computers using Intune and Win32 apps. In this example we’re going to set an BIOS/admin password, but this could of course be expanded to configure other settings that are available through the DellBIOSProvider – https://www.dell.com/support/article/se/sv/sebsdt1/sln311262/dell-command-powershell-provider?lang=en
Note: The Dell PowerShell Provider requires platforms supporting WMI-ACPI BIOS

Mike Terrill posted a great article about using Dell’s PowerShell Provider with ConfigMgr which you can find here: https://miketerrill.net/2016/10/23/how-to-deploy-dell-command-powershell-provider-with-configmgr/

Gary Blok also made a great followup post to Mike’s that you can find here: https://garytown.com/dell-powershell-provider-install-w-configmgr

And while we’re at it, another big thank you and credit to Scott Ladewig and his post about the Visual C++ 2015 requriement for Dell’s PowerShell Provider 2.0 that you can find here: https://www.ladewig.com/dell-powershell-provider-2-0-requires-visual-c-2015/

I ran into a problem trying to import the DellBiosProvider module in the script:

Import Module : Could not load file or assembly ‘DSMBLibWrapper.dll’ or one of its dependencies. The specified module could not be found.

Dell have KB artible about this – https://www.dell.com/support/article/se/sv/sebsdt1/sln308274/dell-command-powershell-provider-is-not-working-properly-or-can-t-be-imported-into-powershell-correctly?lang=en.

That article states that Visual C++ 2010 and 2012 redistruables are needed, which is correct for version 1.x of the DellBIOSProvider module if I’ve understood it correctly. But for version 2.x the requirement is Visual C++ 2015, which Scott’s blogpost points out. He also points out that as you’re not able to install the C++ redistruabables in WinPE, you can get away with just droppiing some of the DLL files in the DellBIOSProvider module folder. Armed with that info, I tested it out and it worked perfectlly in my tests. So instead of packaging the Visual C++ reditruable as it’s own Win32 app and making it a dependecy to the main app, which one could argue is the correct way to do it – I opted for the lazy way of doing it. 😊

Let’s start fetching the files needed for the package. In this example I’ll be using E:\Intune_DellSmBios as my work folder with two sub folders named source and output.

Step 1
Download the DellBIOSProvider module to a folder. Either download it manually the Dell site or with PowerShell:

Save-Module -Name DellBIOSProvider -Path E:\Intune_DellSmBios\source

Step 2
Armed with the info from Scott’s blog about the DLL files, I installed the latest Visual C++ 2015-2019 bundle on a testmachine and copied out the DLL files below into the DellBIOSProvider folder in step 1.  You can download the latest VC++ 2015-2019 bundle from here:

https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads

After installing the bundle, copy the following DLL files from C:\Windows\System32 to the DellBIOSProvider folder:

msvcp140.dll
msvcr120.dll
vcruntime140.dll

Step 3
Final part of the package is the script(s) that does the actual configuration – which is configuring the BIOS admin password in this case. This script works as-is but should be seen as a starting point or proof of concept that should be modified to fit your needs.

Some notes on the script:

$NewPassword = "SecretPassword" 
$OldPassword = "OldSecret"
$DetectionRegPath = "HKLM:\SOFTWARE\Onevinn\Intune\DellBIOSProvider"
$DetectionRegName = "PasswordSet"

$NewPassword – The password we want to set
$OldPassword – The password that is already set and that we want to change from – if applicable
$DetectionRegPath – Registry key that will be created and that will be used for detection method
$DetectionRegName – Name of the registry DWORD that will be set, used as detection method

The first variables obviously needs to be changed to fo the environment. $OldPassword will only actually be used if a BIOS/admin password already is set on the computer.

The Detection variables can be changed to fit your needs, their purpose is to create a regsitry value to use as a detection method if  and when the script has completed successfully.

Passwords in clear text is obviously not great but hardcoding them in the script and deploying it as a Win32 app in this case will at least not show the password in any log files on the clients or in the Intune portal. Ideally the password would be read from a secure vault of some sorts.


Step 4
Save or copy the script to the source folder, in my case: E:\Intune_DellSmBios\source.

Step 5
Download the Microsoft Win32 Content Prep Tool from https://github.com/Microsoft/Microsoft-Win32-Content-Prep-Tool if you haven’t already. Run the tool with the correct paths to create the -.intunewin file.

We should now have a .intunewin file named the same as what was entered as “setup file” in the previous step.

All that’s left now is to create the Win32 app and deploy it to our test user/device. When creating the Win32 app, make sure to use sysnative in the path of the install command. In my case the install command is: C:\Windows\Sysnative\WindowsPowerShell\v1.0\powershell.exe -noprofile -executionpolicy Bypass -file .\DellSmBios-SetAdminPass.ps1. I’m also not using a separate uninstall script/command in this example so I’m just using the same command for both install and uninstall, you can of course change this to whatever fits your scenario.

In the Detection rules pane we will configure a manual detection rule type based on the registry key and value name that we specified in the script. SO in this example that is:

Key path: Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Onevinn\Intune\DellBIOSProvider
Value name: PasswordSet
Detection method: Integer comparison
Operator: Equals
Value: 1

After that we’re done, and we can assign the Win32 app as soon as the file has been uploaded.
To verify we can verify that the  detection rule is there and we also have the transcript/log file in C:\Windows\Temp.

The whole script:

$NewPassword = "eKlient2"
$OldPassword = "eKlient1"
$DetectionRegPath = "HKLM:\SOFTWARE\Onevinn\Intune\DellBIOSProvider"
$DetectionRegName = "PasswordSet"

Start-Transcript -Path "$env:TEMP\$($(Split-Path $PSCommandPath -Leaf).ToLower().Replace(".ps1",".log"))" | Out-Null

if (-not (Test-Path -Path $DetectionRegPath)) {
    New-Item -Path $DetectionRegPath -Force | Out-Null
}

if (Test-Path -Path "$env:ProgramFiles\WindowsPowerShell\Modules\DellBIOSProvider") {
    Write-Output "DellBIOSProvider folder already exists @ $env:ProgramFiles\WindowsPowerShell\Modules\DellBIOSProvider."
    Write-Output "Deleting the folder..."
    Remove-Item -Path "$env:ProgramFiles\WindowsPowerShell\Modules\DellBIOSProvider" -Recurse -Force
}

Write-Output "Copying DellBIOSProvider module to: $env:ProgramFiles\WindowsPowerShell\Modules\DellBIOSProvider" 
Copy-Item -Path "$PSScriptRoot\DellBIOSProvider\" -Destination "$env:ProgramFiles\WindowsPowerShell\Modules\DellBIOSProvider" -Recurse -Force

try {
    Import-Module "DellBIOSProvider" -Force -Verbose -ErrorAction Stop
}
catch {
    Write-Output "Error importing module: $_"
    exit 1
}

$IsAdminPassSet = (Get-Item -Path DellSmbios:\Security\IsAdminPasswordSet).CurrentValue

if ($IsAdminPassSet -eq $false) {
    Write-Output "Admin password is not set at this moment, will try to set it."
    Set-Item -Path DellSmbios:\Security\AdminPassword "$NewPassword"
    if ( (Get-Item -Path DellSmbios:\Security\IsAdminPasswordSet).CurrentValue -eq $true ){
        Write-Output "Admin password has now been set."
        New-ItemProperty -Path "$DetectionRegPath" -Name "$DetectionRegName" -Value 1 | Out-Null
    }
}
else {
    Write-Output "Admin password is already set"
    if ($null -eq $OldPassword) {
        Write-Output "`$OldPassword variable has not been specified, will not attempt to change admin password"

    }
    else {
        Write-Output "`$OldPassword variable has been specified, will try to change the admin password"
        Set-Item -Path DellSmbios:\Security\AdminPassword "$NewPassword" -Password "$OldPassword"
        New-ItemProperty -Path "$DetectionRegPath" -Name "$DetectionRegName" -Value 1 | Out-Null
    }
}

Stop-Transcript

Setting the password is important because knowing the password is a requirement for all future BIOS modifications we need to do in the future, it is of course also a security concern so it should be password protected.