Use PowerShell script to run WSL command - powershell

I can manually open up PowerShell and run
wsl
ip addr show eth0 | grep 'inet\b' | awk '{print $2}' | cut -d/ -f1
To get the IP address of the Ubuntu instance. But when I try to write a script for this (100 different ways) I always get some kind of error. This is an example
$command = "ip addr show eth0 | grep 'inet\b' | awk '{print $2}' | cut -d/ -f1"
$ip = Invoke-Expression "wsl $command"
Which gives an error about grep.

Call wsl.exe via the -e option and specify bash as the executable, which allows you to use the latter's -c option with a command line specified as a single string:
# Note the need to escape $ as `$
# to prevent PowerShell from interpolating it up front inside "..."
$command = "ip addr show eth0 | grep 'inet\b' | awk '{print `$2}' | cut -d/ -f1"
wsl -e bash -c $command
A note re the choice of string literals on the PowerShell side:
Using "..." quoting rather than '...' quoting is convenient if the text contains ' characters, because it obviates the need for escaping - ditto for the inverse scenario: using '...' quoting for text that contains " chars.
However, as in POSIX-compatible shells such as Bash, the choice of the enclosing quoting characters matters in PowerShell, because the resulting behavior differs:
'...' is a verbatim (single-quoted) string.
Unlike in POSIX-compatible shells, where escaping embedded ' chars. must be emulated with '\'', PowerShell does support direct escaping, namely with ''
"..." is an expandable (double-quoted) string, i.e. subject to string interpolation for substrings that start with $
Unlike in POSIX-compatible shells, where embedded $ chars. to be used verbatim (literally) require escaping as \$, in PowerShell you must use `$, using `, the so-called backtick, PowerShell's escape character.

Or let's assume you have powershell installed in linux (there's no Get-NetIPConfiguration?).
$command = "ip addr show eth0 | select-string inet\b | % { (-split `$_)[1] } |
% { (`$_ -split '/')[0] }"
wsl -e pwsh -c $command
10.0.0.107
Or even without it, piping to windows powershell cmdlets.
wsl -e ip addr show eth0 | select-string inet\b | % { (-split $_)[1] } |
% { ($_ -split '/')[0] }
10.0.0.107
$command has to be an array of words:
$command = 'ip address show eth0'
wsl -e (-split $command) | select-string inet\b | % { (-split $_)[1] } |
% { ($_ -split '/')[0] }

Related

how capture stdout output into string that regex can be applied against? [duplicate]

I want to see if I'm running a particular wsl distribution (Windows 10 Home, WSL 2):
PS C:\Users\User> wsl --list --running
Windows Subsystem for Linux Distributions:
Ubuntu (Default)
MyDistro
PS C:\Users\User> wsl --list --running | Select-String -Pattern "MyDistro"
PS C:\Users\User>
No output. I used Get-Member to see that the output is a string; if I run it through something like | Out-String -stream it makes no difference.
I can get a match with Select-String . or Select-String .* but it matches everything, which isn't helpful.
Yes, I want to see if there's a running distro with a particular name. Is there a better way to do that in PowerShell?
Inexplicably, wsl --list --running produces UTF-16LE-encoded ("Unicode"-encoded) output rather than respecting the console's (OEM) code page.
A quick-and-dirty workaround - which assumes that all running distros are described only with ASCII-range characters (which seems likely) - is to use the following:
(wsl --list --running) -replace "`0" | Select-String -Pattern MyDistro
A proper workaround that supports all Unicode characters requires more effort:
$prev = [Console]::OutputEncoding; [Console]::OutputEncoding = [System.Text.Encoding]::Unicode
wsl --list --running | Select-String -Pattern MyDistro
[Console]::OutputEncoding = $prev

Wildcard certificate usage search with Powershell or Command prompt

I have a bash command
curl -v --silent https://abc.xyz/ 2>&1 | grep "CN=\*.xyz.com" -c
this works fine from a Ubuntu machine but I want to convert or use a similar command in Powershell or in CMD. I tried a bunch of variations like:
curl https://abc.xyz/ 2>&1 | Select-String -Pattern "CN=\*.xyz.com"
curl -E -Uri https://abc.xyz/ 2>&1 | Select-String -Pattern "CN=\*.xyz.com"
Invoke-WebRequest https://abc.xyz/ 2>&1 | Select-String -Pattern "CN=\*.xyz.com"
What I noticed in PS commands is, it's not outputting the common name to check the pattern with.
My actual need is to check if the wildcard cert used in https://abc.xyz/ or not.
What am I missing here?
My actual need is to check if the wildcard cert used in https://abc.xyz/ or not.
In this example, we'll check if a wildcard cert is used on msn.com:
$url = 'https://www.msn.com'
$req = [Net.HttpWebRequest]::Create($url)
$req.GetResponse() | Out-Null
$cerName = $req.ServicePoint.Certificate.GetName()
$cerName -match 'CN=\*\.msn\.com'
Output:
True

How to remove the space and display only text (like awk)?

There is a Linux script which is taking docker volume and displaying volumes matches string.
docker volume ls | grep -i $volname | awk '{print $2}'
I need to convert this script to work in windows environment. So PowerShell is my choice. Select-String works more or less like grep.
docker volume ls | Select-String $volname
but there is no equivalent to awk in PowerShell. So I tried to split using whitespace:
$volList = docker volume ls |
Select-String "winvolume" |
foreach { $_ -split " " }
but it has many empty elements (13 empty elements) in the array. I need to remove all the empty elements and have only elements with text. How to achieve this in PowerShell?
Select-String produces MatchInfo objects, from which you need to expand the relevant information first. Use PowerShell operators instead.
((docker volume ls) -match $volname -split ' +')[1]
Splitting at the expression ' +' treats consecutive spaces as a single delimiter, like awk does.
One option is to use the -split operator in a slightly different way. For example, for this string:
"this string has lots of spaces in it "
You can get only the 'words' by doing this:
-split "this string has lots of spaces in it "
Which gives:
this
string
has
lots
of
spaces
in
it
So in your case, your code would be:
$volList = docker volume ls |
Select-String "winvolume" |
foreach { -split $_ }
Another way is to use ConvertFrom-String.
docker volume ls | Select-String winvolume | ConvertFrom-String | ForEach-Object P2
It has an alias:
docker volume ls | sls winvolume | cfs | % P2
Please be aware that if the text contains decimals, they will be rounded. So it is better not to use in scripts

How to convert bash script to powershell my code is here

I want to convert my bash script into powershell, my script is here
sed -i "s/DS_PROP_KEYS :=.*/$DATASOURCE_KEY/OMS_Add_Tenant_Util.sql;"
Without writing a function this is the closest I've seen to replicating sed functionality:
(Get-Content file.txt) | Foreach-Object {$_ -replace "^SourceRegexp$", "DestinationString"} | Set-Content file.txt

Capturing command output in Powershell as string instead of array of strings

I am trying to capture the output of running an external command as a string, but the result returned by Powershell is always an array of strings. It is my understanding that Powershell splits the output on newlines (Windows or Unix line endings) and stores the result in an array, but I would like these newlines to be preserved since this is for an svn pre-commit hook script to detect if a committed file has mixed line endings.
$output = svnlook cat -t $transId -r $repos $filename
At this point line endings have been stripped, and $output is an array of strings, one per line of output.
Redirecting to a file does not seem to work since this normalizes the line endings. How do you tell Powershell to not split a command's output?
Thanks!
Pipe the command output into the Out-String cmdlet:
$output = svnlook cat -t $transId -r $repos $filename | Out-String
Just wrap the "inner" command in parentheses, and use the -join operator with "`n" on the right.
# Preserve line breaks
$result = (ipconfig) -join "`n";
# Remove line breaks
$result = (ipconfig) -join '';
If you need it as a single string, you can just cast the result to [string]
[string]$output = svnlook cat -t $transId -r $repos $filename