Wildcard certificate usage search with Powershell or Command prompt - powershell

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

Related

Use PowerShell script to run WSL command

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] }

Seaching windows environment for a specific value

I want to search the windows environment variables for a specific string
Get-ChildItem -Path Env: | TEE-OBJECT -variable newvar1 | grep windir $newvar1
It works for first time
STDIN
windir C:\WINDOWS
and then fails the subsequent times
grep: Could not open 'System.Collections.DictionaryEntry'
How do i remove old variables from the dictionary (if that is the problem)?
Part 1 - Root Cause
Your core problem is grep windir $newvar1 - the command line parameters for grep are (from https://man7.org/linux/man-pages/man1/grep.1.html):
SYNOPSIS
grep [OPTION...] PATTERNS [FILE...]
DESCRIPTION
grep searches for PATTERNS in each FILE.
You're asking grep to search in a file ($newvar1), not the input stream. Each entry in $newvar1, gets serialised as the literal string System.Collections.DictionaryEntry so grep is basically looking for a file called System.Collections.DictionaryEntry, which doesn't exist.
Part 2 - Solution
The best bet is to go full idiomatic PowerShell and use #JPBlanc's answer, but if you're really wedded to grep just remove the trailing $newvar to use the input stream (stdin) instead of a file for input:
Get-ChildItem -Path Env: `
| TEE-OBJECT -variable newvar1 `
| grep windir
or, if you don't actually need the values stored in $newvar1 for downstream processing, just simply:
Get-ChildItem -Path Env: `
| grep windir
Part 3 - Why no error the first time?
Your original command works the first time because $newvar1 isn't defined yet, so it's equivalent to:
Get-ChildItem -Path Env: `
| TEE-OBJECT -variable newvar1 `
| grep windir $null
... so grep is defaulting to searching the input stream (stdin) rather than a file.
You can confirm this if you enable strict mode - you'll get this error from PowerShell instead:
Set-StrictMode -Version "Latest";
Get-ChildItem -Path Env: `
| TEE-OBJECT -variable newvar1 `
| grep windir $newvar1
# InvalidOperation:
# Line |
# 3 | | grep term $newvar1
# | ~~~~~~~~
# | The variable '$newvar1' cannot be retrieved because it has not been set.
The second time you run the commnad, $newvar1 is already initialised with the results from the first time, so it's equivalent to:
Get-ChildItem -Path Env: `
| TEE-OBJECT -variable newvar1 `
| grep windir "System.Collections.DictionaryEntry"
which, as we've seen, tells grep to look for a file called System.Collections.DictionaryEntry, and results in an error.
Part 4 - More details
Note that $newvar1 isn't defined in the first call to grep because Tee-Object only creates the variable in its End block once it's processed all of its pipeline input (see the source code for Tee-Object.cs on GitHub), which doesn't happen until the entire pipeline has been processed, including the downstream calls to grep.
Not that it's very useful, but you can force the first command to fail by doing this:
(Get-ChildItem -Path Env: | TEE-OBJECT -variable newvar1) `
| grep windir $newvar1
# /usr/bin/grep: System.Collections.DictionaryEntry: No such file or directory
Wrapping the first two expressions in a Grouping Operator forces the pipeline inside to be fully evaluated first, which means Tee-Object's End block creates the $newvar1 variable before grep is invoked, and we get the file-searching behaviour instead of the input stream behaviour.
You an try :
Get-ChildItem -Path Env: | Where-object {$_.value -like 'C:\Users*'}
Get-ChildItem returns a list of objects with properties Name and value. Then Where-object, allow you to filter on these properties, $_ representthe object, you can choose the operator (in this case -like) in the list of Powershell operators).

How to get the first word of output from a PowerShell command

I am trying to get first word from the output of this powershell command
Get-ChildItem -Path Cert:\Certificate::LocalMachine\My | findstr -i ecimas
Which is returning output like:
ffdrggjjhj ecims.example.com
How can I return the string "ffdrggjjhj" only?
You should just be able to split the output like so:
(Get-ChildItem -Path Cert:\Certificate::LocalMachine\My | findstr -i ecimas).split()[0]
Usually powershell looks more like this. Since there's objects, parsing isn't needed.
get-childitem Cert:\LocalMachine\TrustedPublisher | where subject -match wireless |
select -expand thumbprint
ABCDEFABCDEFABCDEFABCDEFABCDEFABCDEFABCD

PowerShell code to export to CSV

I have two Powershell scrips below and they do different things but I need them to do roughly similar things when they export to CSV.
Get-ChildItem C:\Users\user\Desktop\here -Recurse |
where {!$_.PSIsContainer} |
Select-Object * |
Export-Csv -NoTypeInformation -Path C:\Users\user\Desktop\Output\output.csv |
% {$_.Replace('"','')}
Gets me all the detailed info about a directory and when I open the CSV in Excel everything is in separate columns - Perfect.
plink.exe -ssh root#user -pw password -m C:\Users\user\Desktop\Scrips\LinuxScriptCommand.txt > C:\Users\user\Desktop\Output\Linux.csv
Runs df -h on my cloud and returns the space left on my drives, which is what I want, but when I open this CSV in Excel it makes me go through the text import wizard which the other doesn't.
I can't figure out a way to automate the text wizard part, can anyone provide me some insight? Also if you have a way to optimize it please let me know too.
Change your df -h command to output with comma separated values:
df -h | awk '{print $1","$2","$3","$4","$5","$6" "$7}'
The issue you were having with it saving to a single cell is the UNIX line endings not displaying correctly in Windows. This can be fixed by replacing them:
plink.exe -ssh root#user -pw password -m C:\Users\user\Desktop\Scrips\LinuxScriptCommand.txt | foreach {
if (([regex] "`r`n$").IsMatch($_) -eq $false) { $_ -replace "`n", "`r`n" } else { $_ }
} | Set-Content "C:\Users\user\Desktop\Output\Linux.csv"
If you're using a newer version of Powershell you can use the -File param to only return files. Which makes your other command considerably shorter when you remove the other unnecessary parts:
Get-ChildItem C:\Users\user\Desktop\here -Recurse -File | Export-CSV C:\Users\user\Desktop\Output\output.csv -NoTypeInformation

What is the PowerShell equivalent to this Bash command?

I'm trying to create a CLI command to have TFS check out all files that have a particular string in them. I primarily use Cygwin, but the tf command has trouble resolving the path when run within the Cygwin environment.
I figure PowerShell should be able to do the same thing, but I'm not sure what the equivalent commands to grep and xargs are.
So, what would be the equivalent PowerShell version to the following Bash command?
grep -l -r 'SomeSearchString' . | xargs -L1 tf edit
Using some UNIX aliases in PowerShell (like ls):
ls -r | select-string 'SomeSearchString' | Foreach {tf edit $_.Path}
or in a more canonical Powershell form:
Get-ChildItem -Recurse | Select-String 'SomeSearchString' |
Foreach {tf edit $_.Path}
and using PowerShell aliases:
gci -r | sls 'SomeSearchString' | %{tf edit $_.Path}
I find it easier to grok using a variable, e.g.,
PS> $files = Get-ChildItem -Recurse |
Select-String 'SomeSearchString' |
%{$_.path} |
Select -Unique
PS> tf edit $files