Powershell and logparser arguments - powershell

Im trying to run some logparser commands from powershell but Im having issues with passing the arguments across correctly, heres the excert from my script;
d:\scripting\smtplogs\logparser\logparser.exe "SELECT TOP 50 Receiver, COUNT() INTO %TMPOutput%\TopReceiversNDRALL.gif FROM %TempDir%\PostAll.log WHERE Sender LIKE '<>' AND Receiver NOT LIKE '%%go-fmtopper%%' GROUP BY Receiver ORDER BY COUNT() DESC" -i:TSV -iSeparator:space -headerRow:OFF -iHeaderFile:"header3.tsv" -lineFilter:"+10." -o:CHART -chartType:ColumnClustered -config:MyScript.js -chartTitle:"Receivers for NULL messages ALL for %DateGraph%"
Ive read loads about encapsulating arguments but cant seem to figure out how to make this work!
Any help that you guys could provide would be very appreciated.
Thanks

For a complex string parameter, try to pass the argument using powershell here-strings so that you wouldn't have to worry about escaping single/double quotes
UPDATE1: I couldn't get the fomratting working so here is the screenshot.
UPDATE2: I was able to format the code finally.
d:\scripting\smtplogs\logparser\logparser.exe #"
SELECT TOP 50 Receiver, COUNT()
INTO %TMPOutput%\TopReceiversNDRALL.gif
FROM %TempDir%\PostAll.log
WHERE Sender LIKE ''
AND Receiver NOT LIKE '%%go-fmtopper%%'
GROUP BY Receiver
ORDER BY COUNT() DESC"
-i:TSV
-iSeparator:space
-headerRow:OFF
-iHeaderFile:"header3.tsv"
-lineFilter:"+10."
-o:CHART
-chartType:ColumnClustered
-config:MyScript.js
-chartTitle:"Receivers for NULL messages ALL for %DateGraph%
"#
Make sure that you add a new line between the here-string monikers #" and "#.

FYI, if you don't need any PowerShell variable expansion then you are better off using single quoted here strings. For example the following double quoted here string might cause you some grief:
#"
$(get-process <some_core_os_process> | stop-process)
"#
where the following is harmless:
#'
$(get-process <some_core_os_process> | stop-process)
'#
It's not likely your here string would contain something so obvious but a simple $f would resolve to nothing i.e. it would disappear from the original string. Unless, of course, $f was defined and set to something other than null or empty.

Related

Putting Powershell variable in double quotes shows Object type instead of value

I see this problem in several area, but here is an example
I read an xml document like this and print out a value
[xml]$pom = get-content -path pom.xml
PS C:\> $pom.project.artifactId
nexus-peter-test-service
However, if I put the value in double quotes, I get this
"$pom.project.artifactId"
System.Xml.XmlDocument.project.artifactId
I need the value in double quotes because it's part of a long string. In my case, a url. So I'm using it like this:
"/$pom.project.artifactId/"
Why does Powershell change the meaning of the variable when in it's double quotes? And how can I fix this?
The problem is that the interpolation stops at the period. It interpolates "$pom" - which stringifies as the class name - followed by the literal string ".project.artifactId".
To interpolate anything more complex than a simple variable name, you need to wrap $(...) around the expression:
"$($pom.project.artifactId)"

PowerShell string format different behaviour within function

While using powershell I struggle to build up a filename from two variables. When I originally creaded the powershell script, it was working fine. Now I have tried to move some repeatable steps into a function, but the string behaviour is different.
MWE:
$topa = "ABC"
$topb = "XYZ"
function Test-Fun{
param(
$a,
$b
)
echo "$($a)H$($b).csv"
}
echo "$($topa)H$($topb).csv"
Test-Fun($topa, $topb)
The output on my system is
ABCHXYZ.csv
ABC XYZH.csv
Originally, I wanted to use an underscore instead of H and thought that is causing issues, but its not. What did I miss or rather what is the difference between string expansion within a function and outside of it?
You are calling Test-Func wrong. The comma after $topa will create an array, so you basically pass []"ABC", "XYZ" as an array to $a. In that case $b is empty!
You can easily fix this by removing the comma (also the parentheses are not necessary):
Test-Fun $topa $topb

What am I allowed to name a function in Powershell?

PS > function ]{1}
PS > ]
1
PS >
PS
Why does this work?
What else can I name a function? All I've found so far that works is * and ].
You can name it almost anything. You can even include newlines and emoji* in the name.
function Weird`nFunctionの名前😀 { Write-Host hey }
$c = gcm Weird*
$c.Name
& $c
Escaping helps with lots of things like that:
function `{ { Write-Host cool }
`{
function `0 { Write-Host null }
gci function:\?
I'll add that this is true for variables too, and there's a syntax that removes the need to do most escaping in the variable name: ${varname} (as opposed to $varname).
With that, you could easily do:
${My variable has a first name,
it's
V
A
something
R,
whatever I dunno
🤷} = Get-Process
You'll note that if you then start typing like $MyTAB it will tab complete in a usable way.
To (somewhat) answer why this should work, consider that the variable names themselves are just stored in .Net strings. With that in mind, why should there be a limit on the name?
There will be limits on how some of these names can be used in certain contexts, because the parser will not understand what to do with it if the names don't have certain characters escaped, but literal parsing of PowerShell scripts are not the only way to use functions or variables or other language constructs, as I've shown some examples of.
Being less limiting also means being able to support other languages and cultures by having wide support for character sets.
To this end, here's one more thing that might surprise you: there are many different characters to represent the same or similar things that we take for granted in code, like quotation marks for example.
Some (human) languages or cultures just don't use the same quote characters we do in English, don't even have them on the keyboard. How annoying would it be to type code if you have to keep switching your keyboard layout or use ALT codes to quote strings?
So what I'm getting at here is that PowerShell actually does support many quote characters, for instance, what do you think this might do:
'Hello’
Pretty obvious it's not the "right" set of quotes on the right side. But surprisingly, this works just fine, even though they aren't the same character.
This does have important implications if you're ever generating code from user input and want to avoid sneaky injection attacks.
Imaging you did something like this:
Invoke-Expression "echo '$($userMsg -replace "'","''")'"
Looks like you took care of business, but now imagine if $userMsg contained this:
Hi’; gci c: -recurse|ri -force -whatif;'
For what it's worth, the CodeGeneration class is aware of this stuff ;)
Invoke-Expression "echo '$([System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($userMsg))'"
* PowerShell Console doesn't have good support for Unicode, even though the language does. Use ISE to better see the characters.

Powershell remove quotes when start process

Let's look at the code below
$SBK="0x1682CCD8 0x8A1A43EA 0xA532EEB6 0xECFE1D98"
./windows/nvflash/nvflash.exe --sbk 0x1682CCD8 0x8A1A43EA 0xA532EEB6 0xECFE1D98
./windows/nvflash/nvflash.exe --sbk "0x1682CCD8 0x8A1A43EA 0xA532EEB6 0xECFE1D98"
./windows/nvflash/nvflash.exe --sbk $SBK
I have define a string var $SBK and then I'm going to pass it for some app. The first process call is working properly. The second one fails and therefore application doesn't accepts quotes. But the third call is failed too with the same error. It seems that powershell passes quotes, those are causing errors. But how to eliminate them? Thanks beforehand.
Try doing
iex "./windows/nvflash/nvflash.exe --sbk $SBK"
Also, get echoargs.exe from PowerShell Community Extensions to see how args are passed from Powershell to commands etc.
You should probably not use Invoke-Expression (see This Post from the PowerShell Team)
Instead, you can create an array of arguments, and then pass them using the call operator. See this post of mine on the subject for more details.
In your case, it would look something like this:
$SBKArgs="--sbk", "0x1682CCD8", "0x8A1A43EA", "0xA532EEB6", "0xECFE1D98"
$cmd = Get-Command ./windows/nvflash/nvflash.exe
& $cmd $sbkargs
Hope this Helps

Powershell script problem (Get-content vs assigning to variable)

I'm attempting to write a Twitter Powershell script that will use community created interfaces PoshTwitter with the Twitter API to attempt and find a list of followers who are potential spammers.
I have a feeling that my problem lies not with the particular cmdlet I'm calling (Get-TwitterFollowers), but rather with the difference between assigning a variable:
If I try this:
$rawFol = get-twitterfollowers -page $page -raw 1
$rawFol is different than if I do this:
get-twitterfollowers -page $page -raw 1 > .\page$page.txt
$rawFol = gc .\page$page.txt
The Get-TwitterFollowers cmdlet returns an XML file converted to string.
What things can I try to determine the differences between these two assignments? They look like they'd result with same content.
The difference you're seeing is how powershell handles new lines in strings. When calling the get-twitterfollowers CmdLet, it is either returning a single string or an array of strings. My guess by your description is that it returns a string. So the $rawFol variable will have a single string value. Any new lines are simply embedded into the string value.
The second command you write the return to a file. Now all of the newlines in the string are represented as lines in the file. Later when you call gc on that file, each line will be returned as a separate string. So the $rawFol variable will now have an array of strings.