PixelPoSH is a PowerShell module that generates customizable, random SVG backgrounds using the PSSVG DSL (no System.Drawing). It includes patterns like bubbles, concentric circles, stripes, squares, two kinds of waves, and two types of lowpoly. You can add overlay text (single or multi-line), choose colours from palettes (local or colormind.io), and optionally rasterize to PNG using external tools. It's perfect for quickly generating backgrounds for desktops, websites, or any project that could use a splash of color and creativity. PixelPoSH also supports colored text!
Now works on Windows, macOS, and Linux with PowerShell 7+.!
Please see the EXAMPLES.md for sample output.
- Generate SVG at any size (crisp at any resolution).
- Multiple patterns: Bubbles, Circles, Stripes, Squares, PaletteWave, GradientWave (and optional Low-Poly/Delaunay if enabled).
- Overlay text with colour, size, multi-line support, and right-aligned anchoring.
- Optional PNG export via
rsvg-convert,magick(ImageMagick), orinkscape. colormind.ioAPI integration for fetching color palettes.
- PowerShell 7+ (Core)
- PSSVG module
Install-Module PSSVG -Scope CurrentUser
-
(Optional for PNG and the ansible) One of:
- librsvg (
rsvg-convert) - ImageMagick (
magick) - Inkscape (
inkscape)
- librsvg (
Clone the repo and import the module:
git clone https://github.com/dabeastnet/PixelPoSH.git
Import-Module ./PixelPoSH/PixelPoSH.psm1New-RandomImage creates an SVG and saves it to a path. If you don’t specify a path, it defaults to your OS temp directory (e.g., /tmp/Background.svg or %TEMP%\Background.svg).
By default, a random pattern is chosen from:
Bubble, Circle, Stripe, Square, PaletteWave, GradientWave, LowPolyGradient, LowPolyPalette .
For each mode you define yourself, it will randomly select one of the modes.
Below you can find some examples:
The following are the available parameters, with it's default values:
[int]$ImageWidth = 800,
[int]$ImageHeight = 600,
[string]$Path = ([System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), 'Background.svg')),
[string]$Text,
[int]$TextSize = 40,
[string]$TextColor = '#FFFFFF',
[switch]$Bubble,
[switch]$Circle,
[switch]$Square,
[switch]$Stripe,
[switch]$PaletteWave,
[switch]$GradientWave,
[switch]$LowPolyGradient,
[switch]$LowPolyPalette,
[string]$PngPath, #Patch to save the PNG to
[switch]$RasterizeToPng, #Switch to rasterize
[string]$PngBackground = 'none' # or '#ffffff' if you want opaque PNGs by defaultTip: Multi-line text works using backtick-n:
`n(see example below).
Default 800×600 SVG (random pattern)
This command creates an 800x600 svg with a randomly selected pattern and saves it to C:\temp or /tmp/.
New-RandomImage1920×1080 SVG with Squares and custom text
New-RandomImage -ImageWidth 1920 -ImageHeight 1080 `
-Square -Text 'Sample Text' `
-Path "$HOME/Pictures/square-bg.svg"Allow either Bubble or Square (randomly picked)
New-RandomImage -Bubble -SquareMulti-line, coloured text
New-RandomImage -Text "LOLOLOL`nPixelPoSH is 9001`nLOLOLOL" -TextSize 60 -TextColor "#AAFFFF"
# The (backtic) `n is used as a newline indicatorSVG + PNG
New-RandomImage -GradientWave `
-Path "$HOME/Pictures/bg.svg" `
-PngPath "$HOME/Pictures/bg.png"By default, the module tries to fetch a random palette from colormind.io. If offline/unavailable, it uses a built-in set of 100 palettes.
To refresh the embedded palettes, run Get-StaticPalettes.ps1. It writes a Base64 JSON to a file; copy the contents into the Get-ColorPalette subfunction’s $B64Palettes string in PixelPoSH.psm1.
function Get-ColorPalette {
# ...
#region B64
$B64Palettes = "[BASE 64 ENCODED PALETTES GO HERE]"
#endregion B64
# ...
}Encoding tip: JSON is typically UTF-8. Decode with
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String(...)).
Here is an example to display machinename, IP and uptime on the image (Windows example).
#Fetch the info
$IP = (Get-NetIPConfiguration | Where-Object { $_.IPv4DefaultGateway -ne $null -and $_.NetAdapter.Status -eq 'Up' }).IPv4Address.IPAddress
$Uptime = (get-date) - (gcim Win32_OperatingSystem).LastBootUpTime
$FormattedUptime = "{0} days, {1} hours, {2} minutes" -f $Uptime.Days, $Uptime.Hours, $Uptime.Minutes, $Uptime.Seconds
#Generate the image in a yellow text
New-RandomImage -Text "$env:COMPUTERNAME`nIP Address: $IP`nUptime: $FormattedUptime" -TextSize 30 -TextColor "#FFF500"If you enable PNG export in the module, it will try tools in this order: rsvg-convert → magick → inkscape.
Install one of:
- Ubuntu:
sudo apt update && sudo apt install librsvg2-bin - macOS (Homebrew):
brew install librsvg(orbrew install imagemagick) - Windows (winget):
winget install ImageMagick.ImageMagick(Q16 build with SVG support)
A prebuilt image is published to Docker Hub at dabeastnet/pixelposh. It includes PowerShell 7, PSSVG, and librsvg (rsvg-convert) so you can generate SVG and PNG without installing anything locally.
docker pull dabeastnet/pixelposh:latest
# (Optional) always fetch the newest tag:
docker run --pull=always dabeastnet/pixelposh:latest pwsh -c '$PSVersionTable.PSVersion'mkdir -p out
docker run --rm -v "$PWD/out:/out" dabeastnet/pixelposh:latest \
pwsh -NoProfile -c "
Import-Module ./PixelPoSH/PixelPoSH.psm1;
New-RandomImage -GradientWave -Text 'Hello Docker' -Path /out/bg.svg
"docker run --rm -v "$PWD/out:/out" dabeastnet/pixelposh:latest \
pwsh -NoProfile -c "
Import-Module ./PixelPoSH/PixelPoSH.psm1;
New-RandomImage -PaletteWave -Text 'Hello PNG' -Path /out/bg.svg -RasterizeToPng -PngPath /out/bg.png
"- The module inside the image lives at
./PixelPoSH/PixelPoSH.psm1(already on$PSModulePathwhen youImport-Modulewith a relative path as shown). - Default font stack is
Arial, Helvetica, DejaVu Sans, sans-serif. You can mount your own fonts if you need a specific face. - Prefer
:latest(with--pull=always) for convenience, or pin a specific tag/digest for reproducibility.
An opinionated playbook is provided under /ansible to:
- (Best effort) read the target’s resolution
- Generate a random PNG on the controller using PixelPoSH
- Copy it to each target
- Set it as the desktop background (Windows / GNOME / XFCE)
/ansible
├─ inventory # your hosts (ini or yaml)
├─ files/
│ └─ PixelPoSH.psm1 # the module the controller imports
└─ pixelposh_wallpaper_playbook.yml
Make sure
ansible/files/PixelPoSH.psm1matches the version you want to use. The playbook imports it directly from that path on the controller.
From the repo root (or adjust paths accordingly):
ansible-playbook -i ansible/inventory.yml ansible/pixelposh_wallpaper_playbook.ymlProvide a sudo password (only needed for the wallpaper-apply step when you’re not connecting as the desktop user):
ansible-playbook -i ansible/inventory.yml ansible/pixelposh_wallpaper_playbook.yml -K…or set in group_vars (recommend encrypting with Ansible Vault):
# ansible/group_vars/linux.yml
ansible_become: yes
ansible_become_method: sudo
ansible_become_password: YOUR_SUDO_PASS-
Generates the image on the controller in
ansible/files/_out/<hostname>.png -
Copies it to the target:
- Windows →
C:\Windows\Web\Wallpaper\pixelposh.png - Linux →
/tmp/pixelposh_<hostname>.png
- Windows →
-
Sets the wallpaper:
- Windows: Win32
SystemParametersInfo(SPI_SETDESKWALLPAPER)via PowerShell - GNOME:
gsettings set org.gnome.desktop.background picture-uri{,-dark} file:///…(runs as the desktop user; uses the user’s DBus session) - XFCE:
xfconf-queryupdates alllast-imagekeys
- Windows: Win32
- GNOME didn’t change: ensure a desktop session is active for the target user and that
/run/user/<uid>/busexists. If you SSH as another user, the playbook mustbecome_user: <desktopuser>for the gsettings step. - Windows didn’t change: confirm WinRM is configured and the account has rights to update HKCU; a reboot/logoff isn’t required, but Explorer sometimes caches—lock/unlock the session if needed.
- PNG generation failed: the controller needs PowerShell 7 and the module at
ansible/files/PixelPoSH.psm1. The playbook usesrsvg-convert/ImageMagick only if you enable PNG rasterization in your module; our script path uses the built-in rasterization helper.
Contributions to PixelPoSH are welcome! Please feel free to submit pull requests or create issues for bugs and feature suggestions on our GitHub repository.
This project is licensed under the GNU General Public License v3.0 - see the COPYING file for more details.