0

So here is my PowerShell function that I run as part to my OS set up script when creating a new VM on Hyper-V. I am curious is there a better way to accomplish this, or is this a s good as it gets? I would like this to be simpler and easier to implement.

Function Set-ComputerNameOnWallPaper($ComputerName = $env:COMPUTERNAME)
{
#   Pull in the types necesary to manipulate the DesktopWallPaper and the pictures 
#   Information for setting the desktop wallpaper from 
#    https://smulpuru.wordpress.com/2015/04/01/change-wallpaper-using-windows-api-systemparametersinfo-from-user32-dll/
#   Basis for for manipulating the graphic from 
#    http://stackoverflow.com/questions/2067920/can-i-draw-create-an-image-with-a-given-text-with-powershell

$setwallpapersource = @"
using System.Runtime.InteropServices;
public class wallpaper
{
public const int SetDesktopWallpaper = 20;
public const int UpdateIniFile = 0x01;
public const int SendWinIniChange = 0x02;
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SystemParametersInfo (int uAction, int uParam, string lpvParam, int fuWinIni);
public static void SetWallpaper ( string path )
{
SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
}
}
"@
    if (-not ([System.Management.Automation.PSTypeName]'wallpaper').Type){
      Add-Type -TypeDefinition $setwallpapersource
    }
    Add-Type -AssemblyName System.Drawing

#   Get the paths to the current bakground Image
#   Generate a path for the modified Image
#   Genarate a path for a temp file in case the modified image already exists

    $imgInPath  = (Get-ItemProperty 'hkcu:\control panel\desktop\' -Name Wallpaper).Wallpaper
    $imgOutPath = Join-Path -Path $(Split-Path $imgInPath -Parent) -ChildPath $('MyComputerName.jpg')
    $imgTemp   = Join-Path -Path $(Split-Path $imgInPath -Parent) -ChildPath $('Temp01.jpg')

#   Clean up any existing modified images that may have been created by this function

    If ($imgInPath -eq $imgOutPath){       
        Remove-Item -Path $imgTemp -ErrorAction SilentlyContinue
        Copy-Item -Path $imgInPath -Destination $imgTemp 
        [wallpaper]::SetWallpaper($imgTemp)
        $imgInPath = $imgTemp
        Remove-Item -Path $imgOutPath -ErrorAction SilentlyContinue
    }

#   Get the current graphic and define where on that graphic to write the comptername
#   Note: Probably need to add a bit more error handling here

    $top = 850
    $left= 1160 
    $bmp = new-object System.Drawing.Bitmap $imgInPath

    if(($bmp.Width -lt $left) -or ($bmp.Height -lt $top)){
      throw("This function is not configured to work with your Desktop Image size.")
      break
    }

#   Manipulate the image here
#   Set up Font properties   

    $font = new-object System.Drawing.Font Calibri,36 
    $brushFg = [System.Drawing.Brushes]::White

#   Get a default color near where we are going to write 
#   Build the brush      

    $bkgColor=$bmp.GetPixel($left-10,$top-10)  
    $brushClr = [System.Drawing.Color]($bkgColor)
    $brushBg = [System.Drawing.SolidBrush]($brushClr)

#    Fill the possible space where the comptuer name will be written with a default color

    $graphics = [System.Drawing.Graphics]::FromImage($bmp) 
    $graphics.FillRectangle($brushBg,$left-3,$top-3,480,60)  

#   Draw the Comptuer Name

    $graphics.DrawString($ComputerName,$font,$brushFg,$left,$top) 
    $graphics.Dispose() 

#   Save the graphic, clean up the object

    $bmp.Save($imgOutPath) 
    $bmp.Dispose()

#   Set the new Wallpaper and clean up and temporary residue

    [wallpaper]::SetWallpaper($imgOutPath)
    Remove-Item -Path $imgTemp -ErrorAction SilentlyContinue    
}
Joe
  • 1
  • 3
    Is this a for-education project or you just need a computername on background? If the latter, why not use bginfo ? – AlexPawlak Dec 30 '15 at 19:47
  • I didn't want to have to deploy another package on the VM. I use BGinfo on my permanent VMs, these are throw-away, I wanted to be able to quickly identify which VM I was on. Running this script or a slight version of it that takes care of the ACL on img0.jpg, allows me to update that image and move on. – Joe Dec 31 '15 at 17:24

1 Answers1

2

Koliat's suggestion of BgInfo from the Sysinternals suite is probably the best route if you want something that's clean and configurable. No need to reinvent the wheel, unless you're doing it for fun. Take a look at the other utilities as well. Lots of great stuff.

Links:

Booga Roo
  • 1,665
  • 1
  • 21
  • 30