i want to write a script that takes inputfrom the user and changes a word in a file to what the user entered.
saw some people doing it like this:
(Get-Content c:\temp\test.txt).replace('word1', 'word2') | Set-Content c:\temp\test.txt
the problem is that i want to replace a word with a variable, so when i put it between the commas it wont work.
i want it to be something like that:
$word = read-host " please enter a word"
(Get-Content c:\temp\test.txt).replace('oldtext', '$word') | Set-Content c:\temp\test.txt
is there any way to do that?
UPDATE:
tried it like this:
$path = "C:\Users\tc98868\Desktop\dsp.json"
$word = read-host "please enter a word"
(Get-Content $path).replace('dsp.tar.gz', $word) | Set-Content $path
and it still doesnt work.
Remove the single quote from the $word
PowerShell not expanding variables inside a single quote, it threat is as a string
$word = read-host " please enter a word"
(Get-Content c:\temp\test.txt).replace('oldtext', $word) | Set-Content c:\temp\test.txt
For PS Version 2:
(Get-Content c:\temp\test.txt) -replace 'oldtext', $word | Set-Content c:\temp\test.txt
Related
this code supposed to look for all demo.txt in the disk and change them from "demo" to "demodemo997182625" and then check if the file has changed or not
$found = 0;
$notfound = 0;
foreach ($file in Get-ChildItem -Path C:\ -Recurse -Filter demo.txt -ErrorAction SilentlyContinue )
{
(Get-Content $file).Replace("demo","demo997182625") | Set-Content $file
$x = (Get-Content $file).contain("demo997182625")
if($x -eq $null){
$found = 1 + $found;
}
else {
$notfound = 1 + $notfound;
}
}
Write-Host "Changed" $found;
Write-Host "Not Changed" $notfound;
A few remarks on your code:
the .Replace() and .Contains() string methods work case-sensitive, so .Replace("demo","demo997182625") won't find and replace "Demo". To have it work case-insensitively, use the -replace operator instead.
updated files can be reprocessed by Get-ChildItem, unless you have that part finish completely first. The easiest way to do that is by enclosing it between brackets
I would only save the file if there was something updated (i.e. the new value was found after -replace), otherwise leave it be
Get-ChildItem returns both FileInfo and DirectoryInfo objects. Since you are interested in changing files only, append the -File switch
best use the FullName property of the found file on the Get- and Set-Content cmdlets instead of the whole FileInfo object
$found = $notfound = 0
# surround the Get-ChildItem line with brackets, so it will finish before iterating on the result
# otherwise, it could reprocess files that were allready updated
foreach ($file in (Get-ChildItem -Path 'C:\' -Recurse -Filter 'demo.txt' -File -ErrorAction SilentlyContinue)) {
# -replace uses regex, so surround the search string with '\b' boundary markers in order to do a whole-word search
$content = (Get-Content -Path $file.FullName -Raw -Force) -replace '\bdemo\b', 'demo997182625'
# test if the content now has the new value (again, use '\b' boundary markers)
if ($content -match '\bdemo997182625\b') {
# save the updated file
$content | Set-Content -Path $file.FullName -Force
$found++
}
else {$notfound++}
}
Write-Host "Changed: $found"
Write-Host "Not Changed: $notfound"
P.S. If your search string contains characters that in regex have special meaning (see table below), you need to escape these with a backslash when using regex operators -replace and -match.
Special Characters in Regex
Char
Description
Meaning
\
Backslash
Used to escape a special character
^
Caret
Beginning of a string
$
Dollar sign
End of a string
.
Period or dot
Matches any single character
|
Vertical bar or pipe symbol
Matches previous OR next character/group
?
Question mark
Match zero or one of the previous
*
Asterisk or star
Match zero, one or more of the previous
+
Plus sign
Match one or more of the previous
( )
Opening and closing parenthesis
Group characters
[ ]
Opening and closing square bracket
Matches a range of characters
{ }
Opening and closing curly brace
Matches a specified number of occurrences of the previous
I am trying to remove the double quotation marks in the middle of the string field in a CSV file by using a power shell. Please find the attached sample data. Here is the code I am trying but it is not working. please suggest the best solution. thanks in advance.
Get-ChildItem $Outgoing -Filter *.csv | ForEach-Object {
(Get-Content $_.FullName -Raw) | Foreach-Object {
$_ -replace '(?m)(?<=,|^)"([^,"]*)"([^,"]*)"(?=,|$)', '"$1$2"'
} | Set-Content $_.FullName
}
I have a CSV file like:
"localpath"
"C:\Users\calabresel"
"C:\Users\goslinep"
"C:\Users\deangelisr"
"C:\Users\bannont"
"C:\Users\goodwind"
I am looking for a way to isolate just the username from each field. I will then query the AD to determine if each user is disabled or enabled. I haven't been able to figure out how to get just the last piece though. My idea was to use -replace to replace the identical string with null like this:
$txt = import-csv paths1.csv | % {$_.localpath = $_.localpath -replace "C:\Users\", ""}
That came back with invalid regular expression pattern errors though which I assumed was a result of the target string containing special characters (the backslashes). I then started looking for a way to get powershell to take the \ literally instead. That lead me to try this:
$txt = import-csv paths1.csv | % {$_.localpath = $_.localpath -replace [Regex]::Escape("C:\\Users\\"), ""}
and this
$txt = import-csv paths1.csv | % {$_.localpath = $_.localpath -replace "C:\\Users\\", ""}
both of those methods stop the invalid regular expression errors and just return me a fresh line without complaining. however when I print the $txt variable it is empty...
I'm certain I am approaching this problem from the wrong angle and/or with improper syntax but I could use some guidance as I just started working with powershell a week ago.
any help provided would be greatly appreciated.
The following will import the CSV file and then get the leaf of the path. I.e the user name.
$txt = Import-Csv paths1.csv | ForEach-Object { Split-Path $_.localpath -leaf }
If you still want to use your replace method, just take out the $_.localpath = part and it should work.
$txt = Import-Csv C:\##Scatch\test.csv | % { $_.localpath -replace "C:\\Users\\", ""}
The reason why you aren't getting anything back into $txt is that you update a property of $_ but don't return $_.
Assuming that you want to use the regex rather than Split-Path
$txt = import-csv C:\temp\test.csv | % {
$_.localpath = $_.localpath -replace "C:\\Users\\", ""
$_
}
Or
$txt = import-csv C:\temp\test.csv | % {
$_.localpath -replace "C:\\Users\\", ""
}
other solution
Get-Content "C:\temp\test.txt" | select #{N="Value";E={$_.split('\')[-1].replace('"', '')}} -Skip 1
I am writing a super-easy script in PowerShell. The target of this script is to read a list of server names from a txt file and a command block from another txt file. The result of the operation shold be a third txt file containing the information.
Here some code:
cls
$usr = Read-Host "Please insert username, you'll be asked for password later"
$path = Read-Host "Insert a valid path for ServerList.txt file"
$serverList = Get-Content -Path $path | Out-String
$path = Read-Host "Insert a valid path fom Command.txt file"
$commandBlock = Get-Content -Path $path | Out-String
echo "Command: " $commandBlock "will be executed on " $serverList
echo "Press CTRL+Z to abort or"
pause
Invoke-Command -ComputerName $serverList -ScriptBlock { $commandBlock } -credential $usr
Serverlist.txt is a plain text containing something like "server1,server2,server3" and command.txt contain only this "Get-WmiObject Win32_BIOS | Select-Object SerialNumber"
Why the error is Invoke-Command : One or more computer names are not valid. If you are trying to pass a URI, use the -ConnectionUri parameter, or pass URI objects
instead of strings. ?
I even tried to substitute $serverlist with $serverlist.toString() but it's not working. I read somewhere that in this case $serverlist is an Array, how do I do to make everything work?
Consider that https://technet.microsoft.com/en-us/library/hh849719.aspx Invoke-Commands work with "server1,server2,server3" format if you put the string via console.
Your $serverList isn't a list, it's a single string of server1,server2 etc. To make it into an array, you can use -split to split the string by commas.
$serverList = Get-Content -Path $path | Out-String
$serverList = $serverList -split ","
For further understanding of why this doesn't work as you expect, please see the parsing and command syntax help files:
Get-Help about_Parsing
Get-Help about_Command_Syntax
$serverlist
When your text file contains the line server1,server2,server3, this command:
Get-Content -Path .\file.txt | Out-String
Just results in the string server1,server2,server3 and a newline - that's not a valid hostname.
Either format your text file like this (Get-Content automatically splits on line breaks):
server1
server2
server3
or split the string(s) from the file yourself:
$Serverlist = Get-Content -Path $Path | ForEach-Object { $_ -split "," }
$commandblock
For the command block part to work, you can't just drop a string into a ScriptBlock and expect it to execute - you need to recreate it as executable code:
$Code = Get-Content -Path $path -Raw
$CommandBlock = [scriptblock]::Create($Code)
# Now you can do this
Invoke-Command -ScriptBlock $CommandBlock
How to write script in powershell which finds given string in all files in given directory and changes it to given second one ?
thanks for any help,
bye
Maybe something like this
$files = Get-ChildItem "DirectoryContainingFiles"
foreach ($file in $files)
{
$content = Get-Content -path $file.fullname
$content | foreach {$_ -replace "toreplace", "replacewith"} |
Set-Content $file.fullname
}
If the string to replace spans multiple lines then using Get-Content isn't going to cut it unless you stitch together the output of Get-Content into a single string. It's easier to use [io.file]::ReadAllText() in this case e.g.:
Get-ChildItem | Where {!$_.PSIsContainer} |
Foreach { $txt = [IO.File]::ReadAllText($_.fullname);
$txt -replace $old,$new; $txt | Out-File $_}
Note with with $old, you may need to use a regex directive like '(?s)' at the beginning to indicate that . matches newline characters also.
I believe that you can get the list of all files in a directory (simple?). Now comes the replacement part. Here is how you can do it with power shell:
type somefile.txt | %{$_ -replace "string_to_be_replaces","new_strings"}
Modify it as per your need. You can also redirect the output to a new file the same way you do other redirection (using: >).
To get the list of files, use:
Get-ChildItem <DIR_PATH> -name