6

How to update PowerShell scripts using PowerShell

 3 years ago
source link: https://virtuallysober.com/2020/08/04/how-to-update-powershell-scripts-using-powershell/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

How to update PowerShell scripts using PowerShell

Published August 4, 2020 by Joshua Stenhouse
0
inception-paris.jpg?fit=1487%2C646&ssl=1

What if I said you could use PowerShell to update PowerShell? No this isn’t inception, there are legitimate use cases that could save you a lot of time and effort.

I recently had two. First was updating a faulty line of code in a folder of 50+ PowerShell scripts. Why do it by hand when you can automate it? Second was updating a variable on a saved script interactively, enabling users who don’t know PowerShell to update PowerShell. Okay, maybe this is a little inception-esque, but if that sounds interesting then read on.

If you’d like to download my examples, along with some scripts to test with, just click the zip file below, extract, edit and run:

Alternatively, you can copy and paste as go you along.To make this work we are going to use a combination of Get-Content, Read-Host, Select-String, Replace and Set-Content. Let’s start with the simple find and replace of a string in one script:

Pro tip; backup your scripts first!

#############################
# Single line update example
#############################
# Script to edit, change this to your script
$Script = "C:\Demo\DemoScript1.ps1"
# Loading the script content
$ScriptContent = Get-Content $Script
# Enter the line to update
$LineToUpdate = Read-Host "EnterLineToUpdate"
# Enter the new line 
$NewLine = Read-Host "EnterNewLine"
# Selecting the old string
$OldString = $ScriptContent |  Select-String -Pattern $LineToUpdate | Select -First 1
# Only progressing if string found, otherwise nothing to update
IF ($OldString -ne $null)
{
# Creating string required for new line
$NewString = "$NewLine"
# Updating the line
$ScriptModified = $ScriptContent.Replace("$OldString","$NewString") 
# Saving changes to the script
$ScriptModified | Set-Content -Path $Script
}
ELSE
{
"LineNotFound"
}

Pretty cool huh? So how do we run that against all the scripts in a folder? Easy, we can combine it with Get-ChildItem and ForEach:

#############################
# All scripts in a folder line update example
#############################
# Folder of scripts to edit
$ScriptFolder = "C:\Demo"
# Finding all scripts (add -Recurse to Get-ChildItem to get scripts in sub folders)
$Scripts = Get-ChildItem -Path $ScriptFolder | Where {$_.Name -match ".ps1"} | Select -ExpandProperty FullName
# Enter the line to update
$LineToUpdate = Read-Host "EnterLineToUpdate"
# Enter the new line 
$NewLine = Read-Host "EnterNewLine"
# For each script, updating
ForEach ($Script in $Scripts)
{
"Updating: $Script"
# Loading the script content
$ScriptContent = Get-Content $Script
# Selecting the old string
$OldString = $ScriptContent |  Select-String -Pattern $LineToUpdate | Select -First 1
# Only progressing if string found, otherwise nothing to update
IF ($OldString -ne $null)
{
# Creating string required for new line
$NewString = "$NewLine"
# Updating the line
$ScriptModified = $ScriptContent.Replace("$OldString","$NewString") 
# Saving changes to the script
$ScriptModified | Set-Content -Path $Script
}
ELSE
{
"LineNotFound"
}
}

Congratulations! You just updated 1000s of scripts in seconds. But, what if you need to update the setting a variable is configured to? I.E find all scripts with a specific variable and change what is set to. It gets a little tricky at this point because you are entering a variable to update a variable, so here’s how to do it for 1 script:

#############################
# Single file variable update example
#############################
# Script to edit, change this to your script
$Script = "C:\Demo\DemoScript1.ps1"
# Loading the script content
$ScriptContent = Get-Content $Script
# Enter the variable to update
$VariableToUpdate = Read-Host "EnterVariableToUpdate"
# Enter the new variable setting
$NewSetting = Read-Host "EnterNewSetting"
# Selecting the old string
$OldString = $ScriptContent |  Select-String -Pattern $VariableToUpdate | Select -First 1
# Only progressing if string found, otherwise nothing to update
IF ($OldString -ne $null)
{
# Creating string required for new setting
$NewString = "$" + $VariableToUpdate + " = ""$NewSetting"""
# Updating the variable
$ScriptModified = $ScriptContent.Replace("$OldString","$NewString") 
# Saving changes to the script
$ScriptModified | Set-Content -Path $Script
}
ELSE
{
"VariableNotFound"
}

This allowed me to give my users an interactive cmdline using PowerShell to update PowerShell scripts, without them having to know how to edit a PowerShell script to update the setting on a variable. I was particularly pleased with the positive end user impact of such a simple addition.

Here’s how to assign the setting on a variable across multiple scripts:

#############################
# All scripts in a folder variable update example
#############################
# Folder of scripts to edit
$ScriptFolder = "C:\Demo"
# Finding all scripts (add -Recurse to Get-ChildItem to get scripts in sub folders)
$Scripts = Get-ChildItem -Path $ScriptFolder | Where {$_.Name -match ".ps1"} | Select -ExpandProperty FullName
# Enter the variable to update
$VariableToUpdate = Read-Host "EnterVariableToUpdate"
# Enter the new variable setting
$NewSetting = Read-Host "EnterNewSetting"
# For each script, updating
ForEach ($Script in $Scripts)
{
"Updating: $Script"
# Loading the script content
$ScriptContent = Get-Content $Script
# Selecting the old string
$OldString = $ScriptContent |  Select-String -Pattern $VariableToUpdate | Select -First 1
# Only progressing if string found, otherwise nothing to update
IF ($OldString -ne $null)
{
# Creating string required for new setting
$NewString = "$" + $VariableToUpdate + " = ""$NewSetting"""
# Updating the variable
$ScriptModified = $ScriptContent.Replace("$OldString","$NewString") 
# Saving changes to the script
$ScriptModified | Set-Content -Path $Script
}
ELSE
{
"VariableNotFound"
}
}

Warning: all these examples will update all matches found. So remember, with great power comes great responsibility! Happy scripting,

Joshua

Like this:

Loading...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK