I'm working on a script to change the logon background of the computers. I've got it to do everything I need but I'm trying to make the script more efficient, because as it stands, after a new one is chosen, a function I created called OrderNames
is called to rename everything to random, then rename them background1, 2, 3, and so on. Here's a snippet of what I'm working with:
Function OrderNames #Renames everything to a format better than random numbers
{
$FileNames = GCI $BGPath -exclude $BGOld
$FileNames | ForEach-Object -process { Rename-Item $_ -NewName "$Get-Random).jpg" }
$OrderNames = GCI $BGPath -exclude $BGOld
$OrderNames | ForEach-Object -begin { $count = 1 } -process
{ Rename-Item $_ -NewName "background$count.jpg"; $count++ }
}
$Path = "C:\Windows\System32\oobe\info\backgrounds"
$BGOld = GCI $BGPath "backgrounddefault.jpg" #Store current background name
$BGFiles = GCI $BGPath -exclude $BGOld #Get all other images
$BGNew = $BGFiles[(get-random -max ($BGFiles.count)] #Select new image
Rename-Item $BGOld.FullName "$(Get-Random)-$($_.Name).jpg"
Rename-Item $BGNew.FullName "backgrounddefault.jpg"
OrderNames
That works fine and dandy, but I'd like to be able to simply switch the names of $BGOld
and $BGNew
. Back in college with C I could create a temp variable, store BGNew to it, make BGNew equal BGOld and then make BGOld equal temp. But when I create a temp variable with the value of BGOld, it doesn't work. In fact, the variables don't seem to change with the rename function, and setting one equal to the other results in a
Cannot rename because item at does not exist.
Fine, so I tried setting just the name of the file to a variable with Select basename
, but I get an error about
cannot index into an object of type system.io.fileinfo.
Also, I tried $BGOld.FullName = $BGNew.FullName
, tried that with Rename-Item
and a few others I can't remember right now.
I tried to copy the item name but this didn't work either. I'm hoping it's not something simple that I've overlooked.
TL;DR
Is it possible to copy the name of a file into a temp variable, so that when I rename the files, I can copy the name of the temp variable back over to the "old" one to avoid renaming everything? Or even better, can I just switch the filenames?
Yes, you can do something similar in PowerShell. The "algorithm" for this is basically the same as you describe for C:
So the only pieces of information we need to keep track of is the old and new names + the temporary file name.
# Grab the current background and pick the new one
$BGPath = "C:\Windows\System32\oobe\info\backgrounds"
$CurrentBG = Get-Item (Join-Path $BGPath -ChildPath 'backgrounddefault.jpg')
$NewBG = Get-ChildItem $BGPath -Filter *.jpg -Exclude $CurrentBG.Name |Get-Random
# Store the current name of the new background in a variable
$NewBGName = $NewBG.Name
# Now comes the swap operation
# 1. Rename old file to something completely random, but keep a reference to it with -PassThru
$OldBG = $CurrentBG |Rename-Item -NewName $([System.IO.Path]::GetRandomFileName()) -PassThru
# 2. Rename new file to proper name
$NewBG |Rename-Item -NewName 'backgrounddefault.jpg'
# 3. And finally rename the old background back to the name previously used by the new background
$OldBG |Rename-Item -NewName $NewBGName