Skip to content
PowerBGInfo

Wallpaper gallery

Twelve PowerBGInfo wallpapers in light and dark, each with the script that drew it, plus the charts, tables, diagrams and themes they are built from.

Twelve wallpapers, each with one job

Each script answers one question for the person in front of the screen, and each renders in light and dark at any resolution. A theme preset gives each its look and regions place the panels. Every script starts with a data block of fixed samples, so anyone can reproduce the renders, and a comment beside each value names the command that supplies it on a real machine. Three are shown in full here, with the New-BGInfo call that draws each one and the data block it reads.

Hyper-V host

Room for another VM, and which VMs use the host.

  • Corporate theme preset
  • Treemap sized by memory and colored by CPU status bands
  • Metric cards with status bars and a sparkline
  • Progress bars with threshold colors, a table and a list
hyperv-host-light.pnghyperv-host-dark.png PNG 1920 x 1080, 236 KB PNG 1920 x 1080, 241 KB Script on GitHub
Hyper-V host wallpaper for HV-AMS-07: room for 16 GB of VMs before the failover reserve, tiles for CPU, memory, CSV space and running VMs, a treemap of VMs sized by memory and coloured by CPU, cluster memory bars, live migrations and old checkpoints. Hyper-V host wallpaper for HV-AMS-07: room for 16 GB of VMs before the failover reserve, tiles for CPU, memory, CSV space and running VMs, a treemap of VMs sized by memory and coloured by CPU, cluster memory bars, live migrations and old checkpoints. Dark theme.
PowerShellRun.BGInfo.HyperVHost.ps1
New-BGInfo -Theme $look -Target File {
    New-BGInfoBackground -Width $Width -Height $Height -Pattern Grid `
        -PatternSpacing ([int](56 * $scale))
    # A wider right column for the tables; the treemap may fill the center.
    New-BGInfoLayout -ColumnWidth ([int](520 * $scale)) `
        -MaximumPanelHeight ([int](640 * $scale))

    New-BGInfoLabel -Name 'HYPER-V HOST  ·  PRODUCTION CLUSTER' -Accent `
        -FontSize ([int](15 * $scale)) -FontWeight 700
    New-BGInfoLabel -Name $hv.Name -FontSize ([int](72 * $scale)) `
        -FontWeight 600
    New-BGInfoLabel -Name "Room for $free GB of VMs before failover reserve" `
        -FontSize ([int](19 * $scale)) -FontWeight 600
    New-BGInfoValue -Name 'Cluster' -Value $hv.Cluster
    New-BGInfoValue -Name 'Hardware' -Value $hv.Hardware
    New-BGInfoValue -Name 'System' -Value $hv.Version

    # Top band: four host metrics beside the text. Above 80 % memory or
    # 75 % storage the card turns amber; above 90 % it turns red.
    $card = @{ Region = 'Top'; Height = [int](170 * $scale) }
    New-BGInfoMetric @card -Label 'CPU' -Value $hv.Cpu[-1] -Unit '%' `
        -Caption '64 logical cores' -History $hv.Cpu -HistoryMaximum 100 `
        -WarningThreshold 70 -CriticalThreshold 85
    New-BGInfoMetric @card -Label 'Memory' -Value $memory -Unit '%' `
        -Caption "$($hv.MemoryGB) of $($hv.TotalGB) GB assigned" `
        -WarningThreshold 80 -CriticalThreshold 90
    New-BGInfoMetric @card -Label $hv.Storage.Name -Unit '%' `
        -Value $hv.Storage.UsedPercent `
        -Caption "$($hv.Storage.FreeTB) TB free" `
        -WarningThreshold 75 -CriticalThreshold 90
    New-BGInfoMetric @card -Label 'VMs running' -Value $running `
        -Caption "$vcpu vCPU on 64 cores"

    # Center: where the memory goes, grouped by workload. The color is the
    # VM's CPU: amber from 60 %, red from 85 %.
    $hv.Vms | New-BGInfoTreemap -Region Center -Title 'Memory by VM' `
        -Note 'size: memory · color: CPU' -ValueProperty MemoryGB `
        -GroupProperty Workload -ValueSuffix ' GB' -ColorProperty Cpu `
        -WarningThreshold 60 -CriticalThreshold 85

    # Right column: where else VMs could go, today's live migrations and
    # the checkpoints left behind.
    New-BGInfoChart -Region Right -Id 'nodes' -Title 'Cluster memory' `
        -Kind ProgressBar -Values @($hv.Nodes.Values) `
        -Labels @($hv.Nodes.Keys) -Maximum 100 -ValueSuffix ' %' `
        -NoProgressHandles -ShowLatestValue:$false -NoHistory `
        -WarningThreshold 80 -CriticalThreshold 90 `
        -Height ([int](250 * $scale))
    $hv.Moves | New-BGInfoTable -Region Right -Title 'Live migrations' `
        -Note 'today' -Property Time, VM, Result -StatusColumn Result
    New-BGInfoList -Region Right -Title 'Old checkpoints' `
        -Note 'older than 7 days' -Item $hv.Checkpoints
} -ConfigurationDirectory $OutputDirectory `
    -OutputFileName "hyperv-host-$($Theme.ToLower()).png"
#endregion
Full script 170 lines
PowerShellExamples/Run.BGInfo.HyperVHost.ps1
<#
    Hyper-V host. The question for the administrator at this console: does
    this host have room for another VM, and which VMs are using it?

    The data block returns plain values; the presentation block only reads
    them. Comments name the command or source that supplies each value.
#>
param(
    [ValidateSet('Light', 'Dark')]
    [string] $Theme = 'Dark',
    [int] $Width = 1920,
    [int] $Height = 1080,
    [string] $OutputDirectory = (Join-Path $PSScriptRoot 'Output')
)

Import-Module (Join-Path $PSScriptRoot '..\PowerBGInfo.psd1') -Force

#region Data: your logic goes here
function Get-HyperVHostData {
    # Get-VM returns these properties (MemoryAssigned, ProcessorCount and
    # CPUUsage); the workload tag comes from the VM notes or your CMDB.
    # The sample keeps them as CSV to stay short.
    $vms = @'
Name,Workload,vCPU,MemoryGB,Cpu
SQL-PROD-01,Databases,16,128,71
SQL-PROD-02,Databases,16,96,34
SQL-RPT-01,Databases,8,48,12
ERP-APP-01,ERP,12,64,38
ERP-APP-02,ERP,12,64,29
ERP-BATCH-01,ERP,8,32,55
VDI-POOL-A,Desktops,48,96,41
VDI-POOL-B,Desktops,24,48,18
WEB-01,Web,4,16,22
WEB-02,Web,4,16,19
WEB-03,Web,4,16,9
FS-01,Infrastructure,4,32,6
MON-01,Infrastructure,4,24,14
DC02,Infrastructure,2,8,3
'@ | ConvertFrom-Csv | ForEach-Object {
        [pscustomobject] @{
            Name = $_.Name; Workload = $_.Workload; vCPU = [int] $_.vCPU
            MemoryGB = [int] $_.MemoryGB; Cpu = [int] $_.Cpu; State = 'Running'
        }
    }

    [pscustomobject] @{
        Name     = 'HV-AMS-07'
        # Get-Cluster and Get-ClusterNode
        Cluster  = 'HVC-AMS-01 · node 3 of 6'
        Hardware = '2 × Xeon Gold 6448Y · 64 cores'
        Version  = 'Windows Server 2025 Datacenter'
        # Get-Counter '\Hyper-V Hypervisor Logical Processor(_Total)\
        #     % Total Run Time' sampled every 5 minutes
        Cpu      = @(38, 41, 52, 47, 44, 49, 46)
        # (Get-VMHost).MemoryCapacity and the sum of MemoryAssigned
        MemoryGB = [int] ($vms | Measure-Object -Property MemoryGB -Sum).Sum
        # The cluster keeps one node's worth of memory free for failover.
        ReserveGB = 64
        TotalGB  = 768
        # Get-ClusterSharedVolume | Select-Object -ExpandProperty
        #     SharedVolumeInfo | Select-Object -ExpandProperty Partition
        Storage  = @{ Name = 'CSV-02'; UsedPercent = 68; FreeTB = 6.1 }
        Vms      = $vms
        # Get-ClusterGroup | Where-Object OwnerNode -NE $env:COMPUTERNAME,
        # or the Failover Clustering event log, event 5143 and 1641
        Moves    = @(
            [pscustomobject] @{ Time = '09:12'; VM = 'ERP-BATCH-01'
                Move = 'from HV-AMS-04'; Result = 'OK' }
            [pscustomobject] @{ Time = '08:47'; VM = 'WEB-03'
                Move = 'from HV-AMS-02'; Result = 'OK' }
            [pscustomobject] @{ Time = '02:05'; VM = 'VDI-POOL-B'
                Move = 'to HV-AMS-05'; Result = 'Failed' }
        )
        # Memory assigned on every node: Get-ClusterNode | ForEach-Object {
        #     Get-VM -ComputerName $_.Name | Measure-Object MemoryAssigned }
        Nodes       = [ordered] @{
            'HV-AMS-04' = 71; 'HV-AMS-05' = 64; 'HV-AMS-07' = 82
            'HV-AMS-08' = 91; 'HV-AMS-09' = 58; 'HV-AMS-10' = 47
        }
        # Get-VM | Get-VMSnapshot | Where-Object CreationTime -LT
        #     (Get-Date).AddDays(-7)
        Checkpoints = @(
            @{ Text = 'ERP-APP-02 · before CU 14'; Status = 'Warning'
                Value = '12 days' }
            @{ Text = 'WEB-02 · config test'; Status = 'Warning'
                Value = '9 days' }
        )
    }
}

$fallback = [pscustomobject] @{
    Name = $env:COMPUTERNAME; Cluster = 'unknown'; Hardware = 'unknown'
    Version = 'unknown'; Cpu = @(0); MemoryGB = 0; TotalGB = 1; ReserveGB = 0
    Storage = @{ Name = 'CSV'; UsedPercent = 0; FreeTB = 0 }
    Vms = @([pscustomobject] @{ Name = 'unknown'; Workload = ''
            vCPU = 0; MemoryGB = 1; Cpu = 0; State = 'Unknown' })
    Moves = @(); Checkpoints = @(); Nodes = [ordered] @{ 'unknown' = 0 }
}
$source = @{
    Name           = 'Hyper-V host'
    TimeoutSeconds = 20
    ScriptBlock    = ${function:Get-HyperVHostData}
    Default        = $fallback
}
$hv = Invoke-BGInfoDataSource @source
#endregion

#region Presentation: reads only $hv
$scale = [Math]::Round($Height / 1080, 2)
$look = New-BGInfoTheme Corporate -Mode $Theme -Scale $scale
$memory = [Math]::Round(100 * $hv.MemoryGB / $hv.TotalGB)
$running = @($hv.Vms | Where-Object State -EQ 'Running').Count
$vcpu = ($hv.Vms | Measure-Object vCPU -Sum).Sum
$free = $hv.TotalGB - $hv.MemoryGB - $hv.ReserveGB

New-BGInfo -Theme $look -Target File {
    New-BGInfoBackground -Width $Width -Height $Height -Pattern Grid `
        -PatternSpacing ([int](56 * $scale))
    # A wider right column for the tables; the treemap may fill the center.
    New-BGInfoLayout -ColumnWidth ([int](520 * $scale)) `
        -MaximumPanelHeight ([int](640 * $scale))

    New-BGInfoLabel -Name 'HYPER-V HOST  ·  PRODUCTION CLUSTER' -Accent `
        -FontSize ([int](15 * $scale)) -FontWeight 700
    New-BGInfoLabel -Name $hv.Name -FontSize ([int](72 * $scale)) `
        -FontWeight 600
    New-BGInfoLabel -Name "Room for $free GB of VMs before failover reserve" `
        -FontSize ([int](19 * $scale)) -FontWeight 600
    New-BGInfoValue -Name 'Cluster' -Value $hv.Cluster
    New-BGInfoValue -Name 'Hardware' -Value $hv.Hardware
    New-BGInfoValue -Name 'System' -Value $hv.Version

    # Top band: four host metrics beside the text. Above 80 % memory or
    # 75 % storage the card turns amber; above 90 % it turns red.
    $card = @{ Region = 'Top'; Height = [int](170 * $scale) }
    New-BGInfoMetric @card -Label 'CPU' -Value $hv.Cpu[-1] -Unit '%' `
        -Caption '64 logical cores' -History $hv.Cpu -HistoryMaximum 100 `
        -WarningThreshold 70 -CriticalThreshold 85
    New-BGInfoMetric @card -Label 'Memory' -Value $memory -Unit '%' `
        -Caption "$($hv.MemoryGB) of $($hv.TotalGB) GB assigned" `
        -WarningThreshold 80 -CriticalThreshold 90
    New-BGInfoMetric @card -Label $hv.Storage.Name -Unit '%' `
        -Value $hv.Storage.UsedPercent `
        -Caption "$($hv.Storage.FreeTB) TB free" `
        -WarningThreshold 75 -CriticalThreshold 90
    New-BGInfoMetric @card -Label 'VMs running' -Value $running `
        -Caption "$vcpu vCPU on 64 cores"

    # Center: where the memory goes, grouped by workload. The color is the
    # VM's CPU: amber from 60 %, red from 85 %.
    $hv.Vms | New-BGInfoTreemap -Region Center -Title 'Memory by VM' `
        -Note 'size: memory · color: CPU' -ValueProperty MemoryGB `
        -GroupProperty Workload -ValueSuffix ' GB' -ColorProperty Cpu `
        -WarningThreshold 60 -CriticalThreshold 85

    # Right column: where else VMs could go, today's live migrations and
    # the checkpoints left behind.
    New-BGInfoChart -Region Right -Id 'nodes' -Title 'Cluster memory' `
        -Kind ProgressBar -Values @($hv.Nodes.Values) `
        -Labels @($hv.Nodes.Keys) -Maximum 100 -ValueSuffix ' %' `
        -NoProgressHandles -ShowLatestValue:$false -NoHistory `
        -WarningThreshold 80 -CriticalThreshold 90 `
        -Height ([int](250 * $scale))
    $hv.Moves | New-BGInfoTable -Region Right -Title 'Live migrations' `
        -Note 'today' -Property Time, VM, Result -StatusColumn Result
    New-BGInfoList -Region Right -Title 'Old checkpoints' `
        -Note 'older than 7 days' -Item $hv.Checkpoints
} -ConfigurationDirectory $OutputDirectory `
    -OutputFileName "hyperv-host-$($Theme.ToLower()).png"
#endregion

Lines 116 to 170 on GitHub

Help desk

How to get help, plus the details support asks for.

  • Orchid theme preset
  • Generated gradient background with glows and dots
  • Visual canvas info tiles with built-in icons
  • Shared text styles for headings, values and status
Help desk wallpaper: how to reach the service desk, its portal, hours and current service status, with tiles for asset tag, computer name, IP address, signed-in user and Windows version. Help desk wallpaper: how to reach the service desk, its portal, hours and current service status, with tiles for asset tag, computer name, IP address, signed-in user and Windows version. Dark theme.
PowerShellRun.BGInfo.HelpDesk.ps1
New-BGInfo -Theme $look -TextPosition MiddleLeft -Target File {
    New-BGInfoBackground -Width $Width -Height $Height
    # The tile column sits vertically centered beside the centered text.
    New-BGInfoLayout -ColumnAlignment Center

    New-BGInfoLabel -Name 'IT SERVICE DESK' -Accent `
        -FontSize ([int](16 * $scale)) -FontWeight 700
    New-BGInfoLabel -Name 'Need help?' -FontSize ([int](88 * $scale)) `
        -FontWeight 600
    New-BGInfoLabel -Name 'Call 555-0100, extension 4357' -Accent `
        -FontSize ([int](40 * $scale)) -FontWeight 600
    New-BGInfoLabel -Name 'Have the asset tag on the right ready.' -Muted `
        -FontSize ([int](22 * $scale))
    New-BGInfoValue -Name 'Portal' -Value 'help.contoso.com'
    New-BGInfoValue -Name 'Teams' -Value '#it-help'
    New-BGInfoValue -Name 'Walk-in' -Value 'Building B, room 012'
    New-BGInfoValue -Name 'Hours' -Value 'Monday–Friday, 07:00–19:00'

    New-BGInfoLabel -Name ' ' -FontSize ([int](12 * $scale))
    New-BGInfoLabel -Name 'SERVICE STATUS' -Accent `
        -FontSize ([int](16 * $scale)) -FontWeight 700
    foreach ($service in $facts.Services) {
        New-BGInfoLabel -Name "●  $($service.Text)" -Status $service.Status `
            -FontSize ([int](19 * $scale)) -FontWeight 600
    }

    New-BGInfoVisualCanvas -Region Right -Tile $tiles
} -ConfigurationDirectory $OutputDirectory `
    -OutputFileName "helpdesk-$($Theme.ToLower()).png"
#endregion
Full script 107 lines
PowerShellExamples/Run.BGInfo.HelpDesk.ps1
<#
    Help-desk wallpaper for shared or front-desk PCs. It tells people how
    to get help and shows the details the service desk asks for first.

    The data block returns plain values; the presentation block only reads
    them. Sample values keep the render reproducible, and each one notes the
    command that supplies it on a real machine.
#>
param(
    [ValidateSet('Light', 'Dark')]
    [string] $Theme = 'Light',
    [int] $Width = 1920,
    [int] $Height = 1080,
    [string] $OutputDirectory = (Join-Path $PSScriptRoot 'Output')
)

Import-Module (Join-Path $PSScriptRoot '..\PowerBGInfo.psd1') -Force

#region Data: your logic goes here
function Get-HelpDeskFacts {
    [pscustomobject] @{
        # (Get-CimInstance Win32_SystemEnclosure).SMBIOSAssetTag
        AssetTag     = 'CT-04217'
        ComputerName = 'FRONTDESK-07'
        Location     = 'Reception, B1'
        # (Get-NetIPConfiguration |
        #     Where-Object IPv4DefaultGateway).IPv4Address.IPAddress
        IPAddress    = '10.20.4.37'
        Network      = 'Wired · VLAN 120'
        SignedInAs   = 'Reception (shared)'
        # (Get-CimInstance Win32_OperatingSystem).Caption and .BuildNumber
        Windows      = '11 Enterprise 24H2'
        Build        = '26100'
        # Your monitoring or status-page API
        Services     = @(
            @{ Text = 'Email, Teams, Wi-Fi and VPN are working'; Status = 'Ok' }
            @{
                Text   = 'Floor 2 printers are offline until 14:00'
                Status = 'Warning'
            }
        )
    }
}

$fallback = [pscustomobject] @{
    AssetTag = 'unknown'; ComputerName = $env:COMPUTERNAME
    Location = 'unknown'; IPAddress = 'unknown'; Network = ''
    SignedInAs = 'unknown'; Windows = 'unknown'; Build = ''
    Services = @(@{ Text = 'Service status is unavailable'; Status = 'Info' })
}
$source = @{
    Name           = 'Help-desk facts'
    TimeoutSeconds = 10
    ScriptBlock    = ${function:Get-HelpDeskFacts}
    Default        = $fallback
}
$facts = Invoke-BGInfoDataSource @source
#endregion

#region Presentation: reads only $facts
$scale = [Math]::Round($Height / 1080, 2)
$tile = @{ SurfaceStyle = 'Glass' }
$tiles = @(
    New-BGInfoVisualCanvasTile @tile -IconKind Shield -Label 'ASSET TAG' `
        -Value $facts.AssetTag -Detail 'Sticker under the keyboard'
    New-BGInfoVisualCanvasTile @tile -IconKind Computer `
        -Label 'COMPUTER NAME' -Value $facts.ComputerName `
        -Detail $facts.Location
    New-BGInfoVisualCanvasTile @tile -IconKind Network -Label 'IP ADDRESS' `
        -Value $facts.IPAddress -Detail $facts.Network
    New-BGInfoVisualCanvasTile @tile -IconKind User -Label 'SIGNED IN AS' `
        -Value $facts.SignedInAs -Detail 'Resets at sign-out'
    New-BGInfoVisualCanvasTile @tile -IconKind OperatingSystem `
        -Label 'WINDOWS' -Value $facts.Windows -Detail "Build $($facts.Build)"
)

$look = New-BGInfoTheme Orchid -Mode $Theme -Scale $scale
New-BGInfo -Theme $look -TextPosition MiddleLeft -Target File {
    New-BGInfoBackground -Width $Width -Height $Height
    # The tile column sits vertically centered beside the centered text.
    New-BGInfoLayout -ColumnAlignment Center

    New-BGInfoLabel -Name 'IT SERVICE DESK' -Accent `
        -FontSize ([int](16 * $scale)) -FontWeight 700
    New-BGInfoLabel -Name 'Need help?' -FontSize ([int](88 * $scale)) `
        -FontWeight 600
    New-BGInfoLabel -Name 'Call 555-0100, extension 4357' -Accent `
        -FontSize ([int](40 * $scale)) -FontWeight 600
    New-BGInfoLabel -Name 'Have the asset tag on the right ready.' -Muted `
        -FontSize ([int](22 * $scale))
    New-BGInfoValue -Name 'Portal' -Value 'help.contoso.com'
    New-BGInfoValue -Name 'Teams' -Value '#it-help'
    New-BGInfoValue -Name 'Walk-in' -Value 'Building B, room 012'
    New-BGInfoValue -Name 'Hours' -Value 'Monday–Friday, 07:00–19:00'

    New-BGInfoLabel -Name ' ' -FontSize ([int](12 * $scale))
    New-BGInfoLabel -Name 'SERVICE STATUS' -Accent `
        -FontSize ([int](16 * $scale)) -FontWeight 700
    foreach ($service in $facts.Services) {
        New-BGInfoLabel -Name "●  $($service.Text)" -Status $service.Status `
            -FontSize ([int](19 * $scale)) -FontWeight 600
    }

    New-BGInfoVisualCanvas -Region Right -Tile $tiles
} -ConfigurationDirectory $OutputDirectory `
    -OutputFileName "helpdesk-$($Theme.ToLower()).png"
#endregion

Lines 78 to 107 on GitHub

Meeting room

Which room, is it free, and how to share a screen.

  • Orchid theme preset
  • Single-day Gantt lanes for this room and the rooms next door
  • Wi-Fi QR code
  • Numbered list
meeting-room-light.pngmeeting-room-dark.png PNG 1920 x 1080, 194 KB PNG 1920 x 1080, 241 KB Script on GitHub
Meeting room wallpaper for Oslo: free until 13:00, the next booking, a guest Wi-Fi QR code, numbered steps to share a screen and today's bookings beside the neighbouring rooms. Meeting room wallpaper for Oslo: free until 13:00, the next booking, a guest Wi-Fi QR code, numbered steps to share a screen and today's bookings beside the neighbouring rooms. Dark theme.
PowerShellRun.BGInfo.MeetingRoom.ps1
New-BGInfo -Theme $look -Target File {
    New-BGInfoBackground -Width $Width -Height $Height -Pattern None

    New-BGInfoLabel -Name $room.Where -Accent -FontSize ([int](15 * $scale)) `
        -FontWeight 700
    New-BGInfoLabel -Name $room.Room -FontSize ([int](150 * $scale)) `
        -FontWeight 700
    New-BGInfoLabel -Name "●  $($status.Text)" -Status $status.Status `
        -FontSize ([int](34 * $scale)) -FontWeight 600
    New-BGInfoLabel -Name ' ' -FontSize ([int](8 * $scale))
    New-BGInfoValue -Name 'Next booking' -Value $after
    New-BGInfoValue -Name 'Room' -Value $room.Seats
    New-BGInfoValue -Name 'Book it' -Value $room.Book
    New-BGInfoValue -Name 'Help' -Value 'ext. 4357, or help.contoso.com'

    # Right column: guest Wi-Fi on the phone, then how to share a screen.
    New-BGInfoQRCode -Region Right -Text $room.Wifi.Text -Title 'Guest Wi-Fi' `
        -Caption $room.Wifi.Ssid -Note 'scan to join' `
        -Height ([int](330 * $scale))
    New-BGInfoList -Region Right -Title 'Share your screen' -Marker Number `
        -Item $room.Steps

    # Bottom band: today in this room and the two next to it.
    New-BGInfoTimeline -Region Bottom -Title 'Today' -NoLegend `
        -Note 'Bergen and Tromsø are next door' `
        -Item $day -Now $room.Now -Height ([int](280 * $scale))
} -ConfigurationDirectory $OutputDirectory `
    -OutputFileName "meeting-room-$($Theme.ToLower()).png"
#endregion
Full script 138 lines
PowerShellExamples/Run.BGInfo.MeetingRoom.ps1
<#
    Meeting room PC. The question for someone walking in: which room is
    this, is it free, and how do I get my laptop on the screen?

    The data block returns plain values; the presentation block only reads
    them. Comments name the command or source that supplies each value.
#>
param(
    [ValidateSet('Light', 'Dark')]
    [string] $Theme = 'Dark',
    [int] $Width = 1920,
    [int] $Height = 1080,
    [string] $OutputDirectory = (Join-Path $PSScriptRoot 'Output')
)

Import-Module (Join-Path $PSScriptRoot '..\PowerBGInfo.psd1') -Force

#region Data: your logic goes here
function Get-MeetingRoomData {
    $today = Get-Date '2026-10-16'
    # Microsoft Graph: GET /users/{room}/calendarView for today, for this
    # room and its neighbours. One row per booking.
    function Booking($room, $from, $to) {
        $kind = if ($room -eq 'Oslo') { 'This room' } else { 'Nearby rooms' }
        [pscustomobject] @{
            Lane = $room; Category = $kind
            Start = $today.Add([timespan] $from)
            End = $today.Add([timespan] $to)
        }
    }
    [pscustomobject] @{
        Available = $true
        Room     = 'Oslo'
        Where    = 'BUILDING A  ·  FLOOR 4  ·  ROOM 4.12'
        Seats    = '10 seats · video bar · whiteboard'
        Book     = 'Outlook or Teams, room "Oslo 4.12"'
        Now      = $today.AddHours(11).AddMinutes(50)
        Bookings = @(
            Booking 'Oslo' '08:30' '09:30'
            Booking 'Oslo' '10:00' '11:30'
            Booking 'Oslo' '13:00' '14:00'
            Booking 'Oslo' '15:00' '16:30'
            Booking 'Bergen' '09:00' '12:30'
            Booking 'Bergen' '14:00' '15:00'
            Booking 'Tromsø' '08:00' '10:00'
            Booking 'Tromsø' '11:00' '17:00'
        )
        # The guest network: WIFI:T:<WPA|nopass>;S:<SSID>;P:<key>;;
        Wifi     = @{
            Ssid = 'CONTOSO-GUEST'
            Text = 'WIFI:T:nopass;S:CONTOSO-GUEST;;'
        }
        Steps    = @(
            'Plug the USB-C cable on the table into your laptop'
            'Press Share on the touch panel'
            'No cable? In Teams choose Cast, then Oslo'
            'The screen turns off 5 minutes after you leave'
        )
    }
}

$fallback = [pscustomobject] @{
    Available = $false
    Room = $env:COMPUTERNAME; Where = 'MEETING ROOM'; Seats = ''
    Book = 'Outlook or Teams'; Now = Get-Date; Bookings = @()
    Wifi = @{ Ssid = 'CONTOSO-GUEST'; Text = 'WIFI:T:nopass;S:CONTOSO-GUEST;;' }
    Steps = @('Call the service desk on ext. 4357')
}
$source = @{
    Name           = 'Meeting room data'
    TimeoutSeconds = 10
    ScriptBlock    = ${function:Get-MeetingRoomData}
    Default        = $fallback
}
$room = Invoke-BGInfoDataSource @source
#endregion

#region Presentation: reads only $room
$scale = [Math]::Round($Height / 1080, 2)
$look = New-BGInfoTheme Orchid -Mode $Theme -Scale $scale
$here = @($room.Bookings | Where-Object Lane -EQ $room.Room)
$current = $here |
    Where-Object { $_.Start -le $room.Now -and $_.End -gt $room.Now }
$next = $here | Where-Object Start -GT $room.Now | Sort-Object Start |
    Select-Object -First 1
$status = if (-not $room.Available) {
    @{ Text = 'Availability unavailable'; Status = 'Info' }
} elseif ($current) {
    @{
        Text   = "In use until $($current.End.ToString('HH:mm'))"
        Status = 'Warning'
    }
} elseif ($next) {
    @{ Text = "Free until $($next.Start.ToString('HH:mm'))"; Status = 'Ok' }
} else {
    @{ Text = 'Free for the rest of the day'; Status = 'Ok' }
}
$after = if (-not $room.Available) { 'unavailable' } elseif ($next) {
    "$($next.Start.ToString('HH:mm'))–$($next.End.ToString('HH:mm'))"
} else { 'none today' }
# This room takes the accent; the rooms next door stay quiet.
$quiet = $look.Muted.WithAlpha(150).ToHexRgba()
$day = $room.Bookings | Select-Object *, @{
    Name = 'Color'
    Expression = {
        if ($_.Lane -eq $room.Room) { $look.Accent.ToHex() } else { $quiet }
    }
}

New-BGInfo -Theme $look -Target File {
    New-BGInfoBackground -Width $Width -Height $Height -Pattern None

    New-BGInfoLabel -Name $room.Where -Accent -FontSize ([int](15 * $scale)) `
        -FontWeight 700
    New-BGInfoLabel -Name $room.Room -FontSize ([int](150 * $scale)) `
        -FontWeight 700
    New-BGInfoLabel -Name "●  $($status.Text)" -Status $status.Status `
        -FontSize ([int](34 * $scale)) -FontWeight 600
    New-BGInfoLabel -Name ' ' -FontSize ([int](8 * $scale))
    New-BGInfoValue -Name 'Next booking' -Value $after
    New-BGInfoValue -Name 'Room' -Value $room.Seats
    New-BGInfoValue -Name 'Book it' -Value $room.Book
    New-BGInfoValue -Name 'Help' -Value 'ext. 4357, or help.contoso.com'

    # Right column: guest Wi-Fi on the phone, then how to share a screen.
    New-BGInfoQRCode -Region Right -Text $room.Wifi.Text -Title 'Guest Wi-Fi' `
        -Caption $room.Wifi.Ssid -Note 'scan to join' `
        -Height ([int](330 * $scale))
    New-BGInfoList -Region Right -Title 'Share your screen' -Marker Number `
        -Item $room.Steps

    # Bottom band: today in this room and the two next to it.
    New-BGInfoTimeline -Region Bottom -Title 'Today' -NoLegend `
        -Note 'Bergen and Tromsø are next door' `
        -Item $day -Now $room.Now -Height ([int](280 * $scale))
} -ConfigurationDirectory $OutputDirectory `
    -OutputFileName "meeting-room-$($Theme.ToLower()).png"
#endregion

Lines 110 to 138 on GitHub

More wallpapers

Filter by who the screen is for. Each card opens the wallpaper in the page theme with the same Presentation and Data tabs, and links to the full-size PNG and the script on GitHub.

Any screen

A script lays out for the screen it renders on. The on-call board spreads across a 3440 x 1440 ultrawide in the operations room, and the signage script turns a 1080 x 1920 portrait panel into a poster. Each file is drawn at its size, not scaled from 1920 x 1080.

Ultrawide3440 x 1440
The NOC and on-call wallpaper at 3440 x 1440: the on-call engineer and contacts, a runbook QR code and open incidents across the top, and the escalation path and the week's rota spread across the ultrawide. The NOC and on-call wallpaper at 3440 x 1440: the on-call engineer and contacts, a runbook QR code and open incidents across the top, and the escalation path and the week's rota spread across the ultrawide. Dark theme.
Portrait1080 x 1920
The signage wallpaper at 1080 x 1920: Open day in large type with its date, and the QR code and the highlights in two cards at the foot of the portrait screen. The signage wallpaper at 1080 x 1920: Open day in large type with its date, and the QR code and the highlights in two cards at the foot of the portrait screen. Dark theme.

Rendered by Examples/Run.BGInfo.Showcase.ps1 from PowerBGInfo 2f6f22d, every scenario at 1920 x 1080 and these two also at their own screen sizes. Every wallpaper on this page is a script's output, unedited.

PowerShell Download
Loading source…

Themes, regions and widgets

Six theme presets give a wallpaper one look in one parameter, five regions lay it out on any screen, and eight widget cmdlets draw what charts alone cannot.

Six theme presets

Each preset has a light and a dark pair; the page theme picks which one you see. New-BGInfoTheme adjusts a preset's accent, scale or font, and parameters you set always win. Feature.Themes.ps1

PowerShell
New-BGInfo -Theme Midnight -ThemeMode Light { ... }
  • Aurora theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Aurora theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Dark theme.
    Aurora
  • Graphite theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Graphite theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Dark theme.
    Graphite
  • Midnight theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Midnight theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Dark theme.
    Midnight
  • Ember theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Ember theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Dark theme.
    Ember
  • Orchid theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Orchid theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Dark theme.
    Orchid
  • Corporate theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Corporate theme preset: the theme example wallpaper for APP-WEB-02 with a requests card and a CPU chart. Dark theme.
    Corporate

Regions on every screen

One script rendered at three sizes. Left and Right are columns, Top and Bottom are bands and Center sits between them; a panel without a size shares what is left. New-BGInfoLayout keeps the taskbar and the desktop icons clear. Feature.Regions.ps1

PowerShell
New-BGInfoLayout -IconAreaWidth 96 -Gap 24
1920 x 1080
The regions example for FILE-SRV-07 at 1920 x 1080: a left column with a memory card and a CPU chart, a right column with a shares table and volume bars, and a bottom band with network, a CPU gauge and a list. The regions example for FILE-SRV-07 at 1920 x 1080: a left column with a memory card and a CPU chart, a right column with a shares table and volume bars, and a bottom band with network, a CPU gauge and a list. Dark theme.
3440 x 1440
The regions example for FILE-SRV-07 at 3440 x 1440: a left column with a memory card and a CPU chart, a right column with a shares table and volume bars, and a bottom band with network, a CPU gauge and a list. The regions example for FILE-SRV-07 at 3440 x 1440: a left column with a memory card and a CPU chart, a right column with a shares table and volume bars, and a bottom band with network, a CPU gauge and a list. Dark theme.
1080 x 1920
The regions example for FILE-SRV-07 at 1080 x 1920: a left column with a memory card and a CPU chart, a right column with a shares table and volume bars, and a bottom band with network, a CPU gauge and a list. The regions example for FILE-SRV-07 at 1080 x 1920: a left column with a memory card and a CPU chart, a right column with a shares table and volume bars, and a bottom band with network, a CPU gauge and a list. Dark theme.

Widgets

Each widget is one cmdlet that takes plain values, hashtables or the pipeline, and flows into a region like any chart. The crops come from the feature examples; open one for the whole wallpaper. Examples/Features

  • Metric cards

    One value with its trend, a short history and a status from thresholds.

    Metric cards from Feature.Metrics.ps1, cropped to the widget. Metric cards from Feature.Metrics.ps1, cropped to the widget. Dark theme.
    PowerShellFeature.Metrics.ps1
    New-BGInfoMetric -Region Right -Label CPU -Value 38
  • Tables

    Objects in, rows out, with calculated properties and a status column.

    Tables from Feature.Tables.ps1, cropped to the widget. Tables from Feature.Tables.ps1, cropped to the widget. Dark theme.
    PowerShellFeature.Tables.ps1
    $procs | New-BGInfoTable -Region Right
  • Lists

    Numbered steps, checklists and status lists.

    Lists from Feature.Lists.ps1, cropped to the widget. Lists from Feature.Lists.ps1, cropped to the widget. Dark theme.
    PowerShellFeature.Lists.ps1
    New-BGInfoList -Region Right -Item $checks
  • Calendar heatmap

    Days coloured by value: sign-ins, patches, backups or incidents.

    Calendar heatmap from Feature.CalendarHeatmap.ps1, cropped to the widget. Calendar heatmap from Feature.CalendarHeatmap.ps1, cropped to the widget. Dark theme.
    PowerShellFeature.CalendarHeatmap.ps1
    $signIns | New-BGInfoCalendarHeatmap -Region Right
  • Treemap

    Where the space went, by folder, share or virtual machine.

    Treemap from Feature.Treemap.ps1, cropped to the widget. Treemap from Feature.Treemap.ps1, cropped to the widget. Dark theme.
    PowerShellFeature.Treemap.ps1
    $usage | New-BGInfoTreemap -Region Right
  • QR code

    A link a phone can open, encoded by CodeGlyphX and drawn by ChartForgeX.

    QR code from Feature.QRCode.ps1, cropped to the widget. QR code from Feature.QRCode.ps1, cropped to the widget. Dark theme.
    PowerShellFeature.QRCode.ps1
    New-BGInfoQRCode -Region Right -Url $link
  • Timeline

    Maintenance windows, change freezes and the on-call rota in lanes, with a marker for now.

    Timeline from Feature.Timeline.ps1, cropped to the widget. Timeline from Feature.Timeline.ps1, cropped to the widget. Dark theme.
    PowerShellFeature.Timeline.ps1
    New-BGInfoTimeline -Region Bottom -Title 'On call' -Item $schedule
  • Mermaid

    An escalation path or a network flow from a few lines of Mermaid text.

    Mermaid from Feature.Mermaid.ps1, cropped to the widget. Mermaid from Feature.Mermaid.ps1, cropped to the widget. Dark theme.
    PowerShellFeature.Mermaid.ps1
    New-BGInfoMermaid -Region Bottom -Title 'Escalation path' -Definition $diagram

What ChartForgeX draws

PowerBGInfo collects the values, lays out the wallpaper and applies it through Windows. Every pixel of the image comes from ChartForgeX; there is no System.Drawing or browser underneath. A theme preset resolves into the same ChartForgeX light or dark mode for every part, so a wallpaper reads as one design instead of a stack of overlays.