Categories: PowerShell

PowerBGInfo – PowerShell alternative to Sysinternals BGInfo

When I created ImagePlayground, I thought about how to show its usefulness to the general community. On how to deliver what PowerShell can do. Then I saw on some forum people asking BGInfo to expand and allow running PowerShell scripts so that the data on the BGInfo Wallpaper can be gathered from PowerShell rather than VBS. I thought this was a great idea to create BGInfo using PowerShell without the necessity of using BGInfo at all.

Getting and Setting Wallpaper using DesktopManager PowerShell module

Since BGInfo is taking background images and applying text, the idea wasn't challenging. ImagePlayground can already use pictures and texts and apply them pretty quickly. But I was missing an easy way to set a desktop background to a given image or know which image is currently in use. After a quick research, I found that it's mainly registry edits, but then I saw people asking about the 2nd or 3rd monitor, and things weren't as easy at that point, making it a bit more complicated. That's when I decided to create a small PowerShell module called DesktopManager.

I've created Get-DesktopMonitors, Get-DesktopWallpaper, and Set-DesktopWallpaper commands that solve this issue in an easy-to-use way.

Get-DesktopMonitors | Format-Table

Get-DesktopMonitors | Format-Table

Get-DesktopWallpaper -Index 0

Set-DesktopWallpaper -Index 1 -WallpaperPath "C:\Support\GitHub\ImagePlayground\Sources\ImagePlayground.Examples\bin\Debug\net7.0\Images\KulekWSluchawkach.jpg" -Position Fit
Set-DesktopWallpaper -Index 0 -WallpaperPath "C:\Users\przemyslaw.klys\Downloads\IMG_4820.jpg"

Set-DesktopWallpaper quickly sets the new background to a given monitor using its index or MonitorID.

PowerBGInfo - PowerShell alternative to BGInfo

Once DesktopManager was ready to get and set wallpaper, Imageplayground allowed me to modify wallpapers. I was prepared to create PowerBGInfo, an alternative to Sysinternals BGInfo made directly in PowerShell. I'll admit I've not spent ages testing this module regarding the placement of the text, which should probably be improved. The trick with Desktop Background is that your image is not always a direct fit to the resolution. That's why Microsoft added the ability to fit (aka set position) desktop background to current resolution using one of the options such as Center, Fit, Stretch, Fill, Span, or Tile. This means that while ImagePlayground can add text to the right bottom corner of the screen, or the top left corner of the screen without much of an issue, depending on the resolution and position of the wallpaper, it may hide PowerBGInfo content from the screen. You may want to play with it to understand the behavior. What I think could be a future solution is to create a new desktop background (and not reuse the existing one) that is a direct fit for the current screen resolution, but still, that would be different from server to server and the person using it. Let's dive into how to play with PowerBGInfo and achieve the desired results.

New-BGInfo -MonitorIndex 0 {
    # Lets add computer name, but lets use builtin values for that
    New-BGInfoValue -BuiltinValue HostName -Color Red -FontSize 20 -FontFamilyName 'Calibri'
    New-BGInfoValue -BuiltinValue FullUserName
    New-BGInfoValue -BuiltinValue CpuName
    New-BGInfoValue -BuiltinValue CpuLogicalCores
    New-BGInfoValue -BuiltinValue RAMSize
    New-BGInfoValue -BuiltinValue RAMSpeed

    # Lets add Label, but without any values, kinf of like section starting
    New-BGInfoLabel -Name "Drives" -Color LemonChiffon -FontSize 16 -FontFamilyName 'Calibri'

    # Lets get all drives and their labels
    foreach ($Disk in (Get-Disk)) {
        $Volumes = $Disk | Get-Partition | Get-Volume
        foreach ($V in $Volumes) {
            New-BGInfoValue -Name "Drive $($V.DriveLetter)" -Value $V.SizeRemaining
} -FilePath $PSScriptRoot\Samples\PrzemyslawKlysAndKulkozaurr.jpg -ConfigurationDirectory $PSScriptRoot\Output -PositionX 100 -PositionY 100 -WallpaperFit Center

What you see above is following my usual model of building PowerShell modules. There's a primary function called New-BGInfo, which then accepts nested commands New-BGInfoValue and New-BGInfoLabel. The central order you will want to use is New-BGInfoValue which has three main parameters. Those are Label, Value, and BuiltinValue. You can either use Label and Value and provide the name and value however you like, or you can use BuiltinValue, which has some built-in options to save time and effort to create it yourself. If you prefer, you can always use only built-in values, but there are not so many choices for now.

New-BGInfo -MonitorIndex 0 {
    # Lets add computer name, but lets use builtin values for that
    New-BGInfoValue -BuiltinValue HostName -Color Red -FontSize 20 -FontFamilyName 'Calibri'
    New-BGInfoValue -BuiltinValue FullUserName -Color White
    New-BGInfoValue -BuiltinValue CpuName -Color White
    New-BGInfoValue -BuiltinValue CpuLogicalCores -Color White
    New-BGInfoValue -BuiltinValue RAMSize -Color White
    New-BGInfoValue -BuiltinValue RAMSpeed -Color White
} -FilePath "C:\Support\GitHub\PowerBGInfo\Examples\Samples\TapN-Evotec-1600x900.jpg" -ConfigurationDirectory $PSScriptRoot\Output -PositionX 75 -PositionY 75 -WallpaperFit Fill

Some parameters help style both the label and the value. You can use FontFamilyName, FontSize, or Color to style labels and values. If you want, you can also style value separately by using ValueFontFamilyName, ValueFontSize, and ValueColor.

New-BGInfo -MonitorIndex 0 {
    # Lets add computer name, but lets use builtin values for that
    New-BGInfoValue -BuiltinValue HostName -Color Red -FontSize 20 -FontFamilyName 'Calibri'
    New-BGInfoValue -BuiltinValue FullUserName -Color White
    New-BGInfoValue -BuiltinValue CpuName -Color White
    New-BGInfoValue -BuiltinValue CpuLogicalCores -Color White -ValueColor Red
    New-BGInfoValue -BuiltinValue RAMSize -Color White
    New-BGInfoValue -BuiltinValue RAMSpeed -Color White -ValueColor ([SixLabors.ImageSharp.Color]::Aquamarine)
} -FilePath "C:\Support\GitHub\PowerBGInfo\Examples\Samples\TapN-Evotec-1600x900.jpg" -ConfigurationDirectory $PSScriptRoot\Output -PositionX 75 -PositionY 75 -WallpaperFit Fit

You can build your own BGInfo to set on your desktop or server with just three little functions, and you don't have to resort to using anything then a PowerShell module.

Installing / Updating ImagePlayground

PowerBGInfo is available from PowerShellGallery or a download from GitHub. I recommend PowerShellGallery as the source for daily work and GitHub if you wish to play with sources or expand what is already there. Also, any issues, feature requests, and discussions should be pushed to GitHub, as it's the proper way to get support.

Install-Module PowerBGInfo -Force -Verbose

When you use Force, the module will be installed, but when you rerun the command, it will redownload it repeatedly. If there's a new version, it will download the more recent version and leave the old one in place. This makes sure your module is always up to date. Of course, you shouldn't blindly update modules in production. Please test every version before doing the Install-module/Update-module in production.

Install-Module PowerBGInfo -Scope CurrentUser

This module doesn't require Administrative rights on the machine, so you can use the CurrentUser scope as shown above to install it as a standard user.

This post was last modified on January 11, 2023 12:36

Przemyslaw Klys

System Architect with over 14 years of experience in the IT field. Skilled, among others, in Active Directory, Microsoft Exchange and Office 365. Profoundly interested in PowerShell. Software geek.

Published by
Przemyslaw Klys

Recent Posts

Active Directory Replication Summary to your Email or Microsoft Teams

Active Directory replication is a critical process that ensures the consistent and up-to-date state of…

2 months ago

Syncing Global Address List (GAL) to personal contacts and between Office 365 tenants with PowerShell

Hey there! Today, I wanted to introduce you to one of the small but excellent…

7 months ago

Active Directory Health Check using Microsoft Entra Connect Health Service

Active Directory (AD) is crucial in managing identities and resources within an organization. Ensuring its…

8 months ago

Seamless HTML Report Creation: Harness the Power of Markdown with PSWriteHTML PowerShell Module

In today's digital age, the ability to create compelling and informative HTML reports and documents…

10 months ago

How to Efficiently Remove Comments from Your PowerShell Script

As part of my daily development, I create lots of code that I subsequently comment…

10 months ago

Unlocking PowerShell Magic: Different Approach to Creating ‘Empty’ PSCustomObjects

Today I saw an article from Christian Ritter, "PowerShell: Creating an "empty" PSCustomObject" on X…

10 months ago