Powershell - using variables in replace - powershell

I was using .replace until I discovered it is case sensitive.
So I am rewritng a line of code to use -replace instead.
Here is what is working, but is case sensitive:
$SourcePath = 'c:\scripts\test
$folder = 'c:\testing\test'
$sourceFullPath = 'c:\scripts\test\FolderToTest'
$sourceFileRelativePath = $sourceFullPath.Replace($SourcePath, "")
$destFullFilePath = $folder + $sourceFileRelativePath
Write-output $destFullFilePath
c:\testing\test\FolderToTest
How would I convert this to use -replace or is there a way to use the .net .replace case-insensitive?
Note: This section of code will be in a function so they will not be static. I put in examples for this post but they could be any file path.
Thanks!!

Unlike the Replace method which takes strings, the replace operator takes a regular expression pattern. $SourcePath needs to be escaped as it contains backslashes which are special regex characters.
$sourceFileRelativePath = $sourceFullPath -replace [regex]::escape($SourcePath)
$destFullFilePath = Join-Path $folder $sourceFileRelativePath

Related

Powershell Variable assigning issue

I am attemping to make the Destination from the Copy Item function be the $path and keep running into syntax error.
Function movefiles($dayhash){
foreach ($h in $dayhash.GetEnumerator() )
{
$path = "$formsfolderDaily Checklists\$today_($h.Value)"
Copy-Item $formsfolder$($h.Value) -Destination $formsfolder"Daily Checklists\"$today"_"$($h.Value)
editDate($path)
}
Desired outcome
Function movefiles($dayhash){
foreach ($h in $dayhash.GetEnumerator() )
{
$path = $formsfolder + "Daily Checklists\" + $today + "_" + ($h.Value)
Copy-Item $formsfolder$($h.Value) -Destination $path
editDate($path)
}
$path = "$formsfolderDaily Checklists\$today_($h.Value)"
This makes me think $FormsFolder is a path variable with a trailing backslash -- BUT THAT'S JUST A GUESS -- and one of the reasons Join-Path is so useful.
It's also hard to know what is a literal and what is part of a variblbe name when you start constructing complex expansion strings. I would recommend using the -f (Format operator) which nicely separates the literal and variable portions of your string. My best guess for the above would be:
$path = '{0}Daily Checklists\{1}_{2}' -f $formsfolder, $today, $h.Value
Your template string is on the the left-hand side of the operator, with zero-indexed placeholders in the format {0}, {1}, etc. The placeholders correspond to the variables/expressions/function calls found in the list on the right-hand side of the operator.
It sounds like you want to implement your solution using expandable (double-quoted) strings ("...").
To that end, you need to observe two fundamental rules:
In order to disambiguate variable names from subsequent characters, enclose their names in {...}, e.g. $[today} instead of just $today
Notably, _ is a legitimate character in a PowerShell variable name, so if a _ follows a variable reference {...} is needed too.
In order to embed expressions - such as $h.Value - inside "...", enclose them in $(...), the subexpression operator
You've done this in part in your question, but the first command is missing the $ before (.
For a complete overview of PowerShell's string-interpolation rules, see this answer.
Additionally:
You're using compound tokens composed of unquoted and quoted parts in order to form a single string argument, which is best avoided in PowerShell - see this answer.
Instead, use a single, "..."-enclosed string.
Therefore (the assumption is that the value of $formsfolder ends in \ (or /)):
Function movefiles($dayhash) {
foreach ($h in $dayhash.GetEnumerator() ) {
$path = "${formsfolder}Daily Checklists\$today_$($h.Value)"
Copy-Item "${formsfolder}$($h.Value)" -Destination "${formsfolder}Daily Checklists\${today}_$($h.Value)"
editDate $path
}

How to add a line to .txt file with special characters and variables in PowerShell

I have a PowerShell file e.g. C:\MyPowerShell.ps1 and I would like to have the following line there:
$myNewVariable = "Lukas"
Where string Lukas will be taken from variable $name. The variable $name will be declared before I run a command to do this action. I would like to use another PowerShell command to do that.
$name = "Lukas" <br>
Add-Content C:\MyPowerShell.txt ???
Please help me ;-)
Or use the -f Format operator:
$name = 'Lukas'
Add-Content -Path 'C:\MyPowerShell.txt' -Value ('$myNewVariable = "{0}"' -f $name)
Use an expandable (interpolating) string ("...") in which you individually `-escape $ characters in tokens you do not want to be expanded as variable references / subexpressions; similarly, escape embedded " characters as `" ("" would work too):
$name = 'Lucas'
Add-Content C:\MyPowerShell.txt -Value "`$myNewVariable = `"$name`""
Alternatively, use the -f operator, as shown in Theo's helpful answer.
This answer compares and contrasts these two approaches.

Powershell replace between start and end

I need to replace everything between two points.
$import = Get-Content C:\bookmarks.html
$newbody = Get-Content C:\newbookmarks.html
$remove = '(?<=<DT><H3 ADD_DATE=""1544626193"" LAST_MODIFIED=""154649885"">Import-IE</H3>).*?(?=</DL>)'
$import | %{$_.replace($remove,"$newbody")}
My problem is to get all content between start:
<DT><H3 ADD_DATE=""1544626193"" LAST_MODIFIED=""154649885"">Import-IE</H3>
and the end:
</DL>
incl multiple lines
Example html:
<DT><H3 ADD_DATE="1544626193" LAST_MODIFIED="1546498855">Import-IE</H3>
<DL><p>
<DT>golem.de
<DT>heise online
</DL>
Regards
A couple of changes needed to make this work:
One big multiline string
Since you want to do a replace over multiple lines, we need to makes sure all the lines are contained in the same string, so let's start with that - we can use the -Raw parameter switch with Get-Content:
$import = Get-Content C:\bookmarks.html -Raw
Exact pattern matching in regex
Next up we have the regex pattern itself - there's a few discrepancies between that and the sample content you've shown:
LAST_MODIFIED=""154649885"" # pattern has nested double-quotes and only one 5 at the end
LAST_MODIFIED="1546498855" # input uses just one pair of double-quotes and value has two 5's at the end
So let's fix that, and make sure the input string we're looking for is properly escaped while we're at it:
$remove = "(?<=$([regex]::Escape('<DT><H3 ADD_DATE="1544626193" LAST_MODIFIED="1546498855">Import-IE</H3>'))).*?(?=</DL>)"
String.Replace doesn't support regex
Then, we'll have to abandon the String.Replace() method that you're currently using - because it doesn't actually support regex - so we'll use the -replace operator instead:
$import -replace $remove,"$newbody"
Use -replace in SingleLine mode
The only thing we need now, is to instruct the regex parser to treat the input in SingleLine mode - so that .*? will capture newlines as well. This is super easy though, we just add an options flag s at the start of the regex pattern:
$import -replace "(?s)$remove","$newbody"
And that's it :)
$import = Get-Content C:\bookmarks.html -Raw
$newbody = Get-Content C:\newbookmarks.html
$remove = "(?<=$([regex]::Escape('<DT><H3 ADD_DATE="1544626193" LAST_MODIFIED="1546498855">Import-IE</H3>'))).*?(?=</DL>)"
$import -replace "(?s)$remove","$newbody"

Powershell: Comparing a block of text to a file

It certainly seemed like a simple enough task but for whatever reason this doesn't work:
#Verifies that the firefox proxy setting have been applied
#locate Prefsjs file
$PrefsFiles = Get-Item -Path ($env:SystemDrive+"\Users\*\AppData\Roaming\Mozilla\Firefox\Profiles\*\prefs.js")
#read in Prefsjs
$Prefsjs = (Get-Content $PrefsFiles)
#Block to compare
$Update= #"
user_pref("network.proxy.http", "0.0.0.0");
user_pref("network.proxy.http_port", 80);
"#
($Prefsjs -contains $Update)
The last line should return a true because the text actually does exist in $Prefsjs... Any ideas?
It's not going to match because you're comparing a multi-line string to an array of single line strings.
You need to compare like objects, which means $Prefsjs also needs to be a single, multi-line string. The easiest way to do that is to add the -Raw switch to your Get-Content:
#read in Prefsjs
$Prefsjs = (Get-Content $PrefsFiles -Raw)
But now $Prefsjs is not an array any more, so you can't use -Contains. It's now just a single string, so you can use the string contains() method to accomplish the same thing:
$Prefsjs.contains($Update)

How to replace "\" with "\\" using powershell?

I am having a string which contains path.
$Paths = "Myfolder\Mysubfolder"
I need to replace them like "Myfolder\Mysubfolder"
But the $Paths -replace "\","\\" fails as regular expression is unable to find and replace "\".
How to replace then?
You can use .Replace() which does not use regular expressions like this:
$Paths = "Myfolder\Mysubfolder"
$Paths.replace('\','\\')
To use -replace you will need to escape the slash, since it is regex, on the match and not the substitution with the exception of $1 and $2 ...etc which are used a substitution groups.
$Paths -replace '\\','\\'
Result from both is:
Myfolder\\Mysubfolder
I'm thinking an = assignment is required?
$Paths = "Myfolder\Mysubfolder"
write-Host "debug ..... : $Paths"
$Paths = $Paths.Replace("\","\\")
write-Host "debug ..... : $Paths"
This gives:
debug ..... : Myfolder\Mysubfolder
debug ..... : Myfolder\\Mysubfolder