Bart Simons

windows

A 3 post collection


Export Windows drivers with PowerShell

 •  Filed under export, windows, drivers, powershell

Need to reinstall Windows, but don't want to go through the hassle of getting all the needed drivers onto your new Windows installation? There's an easier way to work around that by using PowerShell! Just two cmdlets Get-WindowsDriver and Export-WindowsDriver are needed for this operation.

Obtaining a list of drivers is the first thing to do. You can use the Online and All flags to get a list of all the drivers from the currently running operating system. We put the output into a variable to be able to filter stuff later on:

$Drivers = Get-WindowsDriver -Online -All

Let's see out of which objects the variable exists so we can apply filters on this object:

PowerShell Driver Object

We can tell now that it's possible to filter on

  • Driver name;
  • Driver storage location and name;
  • Driver provider/manufacturer name;
  • Driver class/type;
  • Driver version;

You can also filter on date value, inbox value and boot criticality but it doesn't really bother me that much. If I want to fetch device drivers from a specific manufacturer for example, I can use this command:

$Drivers | where { $_.ProviderName -like "NVIDIA" }

Or if I want to list all types of drivers, I can use this:

$Drivers.ClassName | Sort-Object | Get-Unique

What if I wanted to get a list of all my network drivers?

$Drivers | where { $_.ClassName -like "*Net*" }

In case you need to export your drivers for e.g. migration purposes, this is what you want to run:

Export-WindowsDriver -Online -Destination "C:\Drivers"  

Especially the last command seems very useful to me. Next time I have to reinstall Windows, I know what to do 😉

Properly disabling Easy of Access at the Windows Login Screen

 •  Filed under windows, security, login screen, ease of access, disable

Do you know about that tiny little blue button at the lower left corner of the Windows 7 login screen? When an unknown person clicks that button on your computer while you are away for a quick snack or some coffee, he/she will be able to do the following to your computer:

Ruined Login Screen

Even though it can be reverted back easily, it might be better to disable this button on the lock screen. Please note that this trick works on all Windows versions, including Windows 10!

So let's get started by taking ownership of the Utilman.exe file located in the System32 folder.

Start by bringing up a command prompt in administrator mode, and use the following command to get permissions

takeown /f C:\Windows\System32\Utilman.exe

You should get a confirming message claiming that the executable is now owned by your user account. Great, now let's fiddle around with the executable and it's permissions. Navigate to the System32 folder and locate the Utilman executable file. Right click on it, and click on properties. You should get this window

Utilman.exe properties window

Click on the Security tab, click on the SYSTEM user in the upper list, and then click on the Edit button.
Read and Read & Execute rights should be disabled like this

Utilman.exe permissions

Click on Apply and you should be good to go!

Can PowerShell replace your old batch installation scripts?

 •  Filed under powershell, batch, automation, scripting, windows

PowerShell can be a very useful scripting language for specific tasks. Back in the old days batch scripts were the way to go for software deployment automation, often shipped with other executables to extend functionality. PowerShell adds tons of available features in one package by Microsoft, which was not possible with just a single bash script. My goal was to create a script that automates the deployment of Git for Windows, with features like architecture detection and more.

The plan

A great project always starts with a great plan, so here is a feature list that I have written and used for the development process of the script:

  • 32/64-bit detection;
  • Install path in the current user's PATH-variable;
  • Download the latest version of Git for Windows and VLC;
  • Remove any left over files automatically

Fetching installation files at runtime

Another great thing about PowerShell is that it perfectly integrates with the .NET framework. For example, you can create new .NET objects with the New-Object function. Here's a working example to download a file from the internet to your computer:

<# Simple download script demonstration #>

$SystemDrive = $env:SystemDrive
$downloadFile = "http://get.videolan.org/vlc/2.2.3/win32/vlc-2.2.3-win32.exe";
$destinationFile = "$SystemDrive\Users\Bart\Desktop\vlc-x86.exe";

(New-Object System.Net.WebClient).DownloadFile($downloadFile, $destinationFile);

There are also different ways of downloading files in PowerShell, but this is the fastest way of getting the job done. The minimal PowerShell version required to run this script is version 2. An alternative way of downloading files, called Invoke-WebRequest was introduced in PowerShell version 3 and that explains why this command didn't work on a Windows 7 install.

Architecture detection

Most software vendors supply their applications as a 32-bit and 64-bit version, and since PowerShell is able to work with WMI, you can just obtain the needed information from the Win32_OperatingSystem WMI class. Here's a code snippet to check the OS architecture:

<# Simple script to detect OS architecture #>

$OSArch = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
If ($OSArch -eq "64-bit") {  
    Write-Host "OS is 64-bit!";
} ElseIf ($OSArch -eq "32-bit") {
    Write-Host "OS is 32-bit!";
}

You can replace the code located within the If statements with your own code.

Running software installers

Powershell can start processes for you with the needed arguments, wait for the process to complete and then it can delete the installer file for you. The PowerShell functions needed for this are Start-Process and Remove-Item. Here's an example:

<# Simple script to start the installation + cleanup afterwards #>

$SystemDrive = $env:SystemDrive
Start-Process "$SystemDrive\Users\Bart\Desktop\vlc-x86" -ArgumentList "/L=1033 /S" -Wait  
Remove-Item "$SystemDrive\Users\Bart\Desktop\vlc-x86.exe"  

Append directory to PATH variable

Appending the installation directory requires a little bit more programming work and knowledge. Here is an example script for you that appends the VLC installation path to your current user's PATH-variable:

<# Simple script to append the current user's path variable #>

$SystemDrive = $env:SystemDrive
$VLCPath = "C:\Program Files";

Try {  
    $Path = (Get-ItemProperty -Path 'HKCU:\Environment' -Name PATH -ErrorAction Stop).PATH
    If ($Path -ne "") {
        $NewPath = "$Path;$SystemDrive\Program Files\VideoLAN\VLC";
    } Else {
        $NewPath = "$SystemDrive\Program Files\VideoLAN\VLC";
    }
    Set-ItemProperty -Path 'HKCU:\Environment' -Name PATH -Value $NewPath
} Catch {
    If ($_.Exception.Message -like "Property PATH does not exist at path HKEY_CURRENT_USER\Environment.*") {
        New-ItemProperty -Path 'HKCU:\Environment' -Name PATH
        $NewPath = "$SystemDrive\Program Files\VideoLAN\VLC";
        Set-ItemProperty -Path 'HKCU:\Environment' -Name PATH -Value $NewPath
    } Else {
        Write-Host "Unknown error.";
    }
}

As you can see, this script works with the registry. At first, the script tries to obtain information from the HKEY_CURRENT_USER\Environment\PATH item which does not exist by default, which results in an error catched by the Catch handler that creates the needed registry entry for you automatically.

The full script

Here is the full script for installing VLC Player:

<# Install-VLC.ps1 - An automated installation script for the VLC Player #>  
<# Made by Bart Simons - https://bartsimons.me #>  
$SystemDrive = $env:SystemDrive
$User = [Environment]::UserName
$destinationFile = "$SystemDrive\Users\$User\Desktop\vlc.exe";

$OSArch = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
If ($OSArch -eq "64-bit") {  
    $downloadFile = "http://get.videolan.org/vlc/2.2.3/win64/vlc-2.2.3-win64.exe";

} ElseIf ($OSArch -eq "32-bit") {
    $downloadFile = "http://get.videolan.org/vlc/2.2.3/win32/vlc-2.2.3-win32.exe"
}

(New-Object System.Net.WebClient).DownloadFile($downloadFile, $destinationFile);

Start-Process "$SystemDrive\Users\$User\Desktop\vlc.exe" -ArgumentList "/L=1033 /S" -Wait  
Remove-Item "$SystemDrive\Users\$User\Desktop\vlc.exe"  


Here is the full script for deploying Git for Windows:

<# Deploy-Git.ps1 - An automated deployment script for Git #>  
<# Made by Bart Simons - https://bartsimons.me #>  
$SystemDrive = $env:SystemDrive
$User = [Environment]::UserName
$destinationFile = "$SystemDrive\Users\$User\Desktop\git.exe";

$OSArch = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
If ($OSArch -eq "64-bit") {  
    $downloadFile = "https://github.com/git-for-windows/git/releases/download/v2.8.3.windows.1/PortableGit-2.8.3-64-bit.7z.exe";

} ElseIf ($OSArch -eq "32-bit") {
    $downloadFile = "https://github.com/git-for-windows/git/releases/download/v2.8.3.windows.1/PortableGit-2.8.3-32-bit.7z.exe"
}

(New-Object System.Net.WebClient).DownloadFile($downloadFile, $destinationFile);

Start-Process "$SystemDrive\Users\$User\Desktop\git.exe" -ArgumentList "-y -gm2 -InstallPath=`"$User`"" -Wait  
Remove-Item "$SystemDrive\Users\$User\Desktop\git.exe"  

Try {  
    $Path = (Get-ItemProperty -Path 'HKCU:\Environment' -Name PATH -ErrorAction Stop).PATH
    If ($Path -ne "") {
        $NewPath = "$Path;$SystemDrive\Users\$User\git\bin";
    } Else {
        $NewPath = "$SystemDrive\Users\$User\git\bin";
    }
    Set-ItemProperty -Path 'HKCU:\Environment' -Name PATH -Value $NewPath
} Catch {
    If ($_.Exception.Message -like "Property PATH does not exist at path HKEY_CURRENT_USER\Environment.*") {
        New-ItemProperty -Path 'HKCU:\Environment' -Name PATH
        $NewPath = "$SystemDrive\Users\$User\git\bin";
        Set-ItemProperty -Path 'HKCU:\Environment' -Name PATH -Value $NewPath
    }
}