Browsing the archives for the powershell tag.


PowerShell’s NOT IN operator

Software

Were I to write some SQL to see if an element was not present in a set, I’d write something like:

SELECT T.*
FROM [table] T
WHERE T.[name] NOT IN (“foo”, “bar”, “bat”)

How to do the same type of thing in PowerShell 2.0?  Well, you can’t – not the same way.  But flip it on its head, and you get exactly the same thing:

$myvalue = “something” #this is the T.[name] from the SQL example
$arr = “foo”, “bar”, “bat”
($arr –contains $myvalue) -eq $false

You have an additional tweak available to you: a case-sensitive comparison.  To do this, use –ccontains (note the extra “c”) instead of –contains:

$arr –ccontains $myvalue

To find out more about comparison operators in PowerShell 2.0, type:

get-help about_comparison_operators

in the IDE.

Finally, a neat trick: if you know that there’s an “about_” topic, but are not sure what it is?  get-help accepts partial matches:

get-help about_

… will return all the help topics that start with the string “about_”.  Pretty neat.

1 Comment

PowerShell: Remove the Expect 100-Continue Header

Software

I’m running some scripts against the YouMail API to post audio.  I’m seeing HTTP 417 Expectation Failed messages, which The Google has led me to believe are due to the Expect: 100-Continue header present in the post.

Fiddler tells me that yes indeedy, I’m passing the Expect: 100-Continue header:

image

So, back in PowerShell, I add the following line of code:

[System.Net.ServicePointManager]::Expect100Continue = $false

… but I see the same problem.

Checking the ServicePointManager and the HttpWebRequest object for their properties gives me two different results:

§ anthonys-m1330 {C:\s\C\Test-YouMail} [System.Net.ServicePointManager]::Expect100Continue
False
______________________________________________________________________________________________
§ anthonys-m1330 {C:\s\C\Test-YouMail} $req.Expect
100-continue

So what’s the deal?  Turns out that you have to set the Expect header property on the HttpWebRequest object directly:

$req.Expect = ""

…which clears out the Expect: 100-Continue header.

This begs the question, what does the System.Net.ServicePointManager have to do with anything?  Dunno.

No Comments

Interesting PowerShell XML Encoding Bug

Software

I was dinking around with the System.Xml namespace in PowerShell this morning and came across an interesting encoding bug.  Here’s the PowerShell function to read XML data from a file and return a System.Xml.XmlDocument object:

function Get-XmlDocumentFromFile() {
param([string]$file)
Write-Host("Reading the file {0} for XML content..." -f $file)
if ((Test-Path $file) -eq $false) {
throw(("ERROR: File not found! '{0}'" -f $file))
}
[xml]$xml = new-object System.Xml.XmlDocument
try
{
$xml.Load($file)
$xml
}
catch [System.Exception]
{
$_ | fl * -Force
}
}

When I call this function with this XML file as input:

<?xml version="1.0" encoding=”UTF-8” ?>
<entry>
</entry>

I get this error:

Cannot convert value "System.Object[]" to type "System.Xml.XmlDocument". Error: "Data at the root level is invalid. Line
1, position 1."
At line:1 char:3

However, if I change the XML declaration in the file to this:

<?xml version="1.0" ?>
<entry>
</entry>

…it works.  So what is it about the “UTF-8” encoding attribute that causes it to barf in PowerShell?  Dunno.  Will investigate more later.  But that “Data at the root level is invalid” error is what pointed me at the problem.  My first cut at the PS function didn’t include the exception handler and I got this unhelpful and misleading error:

Root element is missing

… which was obviously incorrect on its face.  So, moral: always include exception handlers in your PS functions.

No Comments

HOWTO: Get a Base64 Encoded String From a WAV file in PowerShell

Software

This little function may be useful to you long-tail Google searchers:

function Get-BytesFromWav(){
param([string]$wavFile)
Write-Host ("Getting bytes from the file {0}..." -f $wavFile)
if ((Test-Path $wavFile) -eq $false) {
throw("File not found!")
}
[System.IO.FileStream]$stream = [System.IO.File]::OpenRead($wavFile)
[byte[]]$b = @($null) * 1024
[System.Text.StringBuilder]$sb = new-object System.Text.StringBuilder
while ($stream.Read($b,0,$b.Length) -gt 0)
{
$b64 = [Convert]::ToBase64String($b)
#make sure to handle the return value
$temp = $sb.Append($b64)
}
$sb.ToString()
}

2 Comments

PowerShell: Watch Those Implicit Return Values!

Software

One thing about PowerShell that tends to bite me fairly often is the handling of return values from functions. PowerShell doesn’t have an explicit RETURN statement, so functions will return anything that’s not handled. Consider the following:

function Foo() {
[System.Text.StringBuilder]$sb = new-object System.Text.StringBuilder
$sb.AppendLine("foo")
$sb.AppendLine("bar")
$sb.AppendLine("bat")
$sb.ToString()
}

What’s the return value of this function? One might at first suspect that it is:

foo
bar
bat

…but you’d be wrong. What it actually outputs is a bunch of duplicates, because each .AppendLine() call returns SOMETHING, and that something happens to be the StringBuilder instance. And you may run into an implicit .ToString() if you’re using the return value, so…it’s just bad news all around.

The solution is to explictly handle anything you don’t want to return:

function Foo() {
[System.Text.StringBuilder]$sb = new-object System.Text.StringBuilder
$temp = $sb.AppendLine("foo")
$temp = $sb.AppendLine("bar")
$temp = $sb.AppendLine("bat")
$sb.ToString()
}

It’s a little gnarly, but workable.

No Comments

PowerShell 2.0 “More” command in the ISE

Software

Back in the good old days of the DOS command prompt, you frequently wanted to break up a large chunk of results into pages, that you could scroll through using the spacebar.

For example:

help | more

Would show one page of help information at a time.

Does PowerShell 2.0 support the “more” command? Well, it depends.  It depends on if you’re using the “standard” PowerShell.exe command prompt, or the PowerShell_ISE.exe (Integrated Scripting Environment).  The behavior is different depending on which tool you use.

I use the ISE quite a bit.  It’s not a perfect editor – far from it – but I like the ability to have files open and to be able to interactively run parts of scripts via the F8 “run selection” option.

However, in PowerShell ISE, all of the “more” business goes away.  PowerShell ISE doesn’t do a good job of interactively working with results.

So, for example, in PowerShell ISE, if you type:

mysql –? | more

… you won’t get any paging.  Everything will just spit out to the end.

PowerShell has a cmdlet called Out-Host with a –Paging parameter, which theoretically should give us something, but in my tests it just hangs the ISE IDE.  Even the example given in Get-Help Out-Host:

get-process | out-host –paging

Returns with the error:

image

out-lineoutput : The method or operation is not implemented.

So, moral: if you want to do interactive stuff with PowerShell, such as FTP, MySQL, or pipe to “more” to page results, use the standard PowerShell 2.0 command prompt, and stay away from the ISE. For now.

1 Comment

The Perky One

Personal

From an article about a Katie Couric photo shoot for Harper’s Bazaar:

Couric calls herself a joyful person. "I mean, hello? Yes. I am. I am! And unashamed that I’m not cynical or dark or ironic."

I’ve never been the world’s biggest Couric fan, but her Sarah Palin interview from late 2008 cracked the ice, and now I find she’s an irrepressibly joyful person and I’m all agog and giggly and aw-shucks and toe-twistingly blushing over The Perky One.

I still won’t watch CBS Evening News, or any other network news show for that matter, because I loathe lowest-common-denominator sensationalism that deals almost exclusively with violence or hate or pain or anger or catastrophe or extremism, but the producers have the control over that stuff.

It’s been a good couple days.  My team completed the iteration in style, finishing all our commitments and making headway on some important analysis that put us in a good place during upcoming iterations.  I have a good team, and I am very lucky to work with them.

Gratitude is back on my mind again today – a random blog post elsewhere talked about it.  I ask myself am I expressing gratitude as much as I could? I don’t know, I guess that’s a never-ending question.  Plenty of people are deserving of my gratitude.  Thinking about it, I can think of times each day for the past few days where I’ve made special mention of someone who has done something nice or what have you.  Is it becoming second nature?  Would a friend describe me as someone who expresses well-deserved gratitude?  I hope so.

I’ve been doing some deep-dive exploration of PowerShell’s WMI provider and am thinking about adding yet more to my plate by doing a short series of blog posts for the smart-but-new-to-PowerShell developer about how to use WMI.  It’s powerful stuff.  And I’m guessing that those kind of posts will be hugely popular for the right search engine terms, because the current documentation is pretty thin.

Two people have told me that they felt “stalker-ish” by going to my blog to find out more about me.  I have to laugh – I put so much out there, that if I had any stalkers, they’d basically be able to find out anything they want, and know exactly where I go, almost all the time.  There is however, a part of me that occasionally wishes I could be even MORE open, MORE transparent, MORE clear – but there are some topics that are still taboo in this era where we expose almost everything.  Not to mention that if I write about it, it becomes more real, and sometimes I just want to forget, to move on, to seek out new worlds, to boldly go where no man has gone before…sorry, I digressed into a Star Trek moment there.  But writing-as-catharsis has a counterargument, writing-as-disguising-reality, and I don’t want to breathe life into something that’s bothering me by worrying it to death on these pages.  Maybe I’m bothered for no good reason, or I’m properly bothered and the appropriate response is just to ignore it and move on.  Blogging about it would just give it legs.

Which brings me to another recently reoccurring topic, Other People’s Comments.  I’m on much better terms today with a couple things that were said that hurt my feelings than I was, say, a week ago.  Stuff gets said.  Deal.  It helps when you realize that no malice was intended.

Big night of coding tomorrow night – wonder what coffee shop I’ll be at.  Probably Zoka, unless a better idea presents itself.  Then more work this weekend, intermixed with some time with the kids and (maybe) watching the Super Bowl.  Maybe I’ll look around for a Super Bowl party that a friend is already throwing and bring some chips and beer and Drew Brees jokes.

Wow, another novel!  Yay me. Thank you for reading. :)

1 Comment

Recursively Deleting SVN Folders in PowerShell 2.0

Software

I ran across this little nugget of PowerShell wisdom when working up a script to recursively delete those hidden .svn folders in your local working copy: PowerShell can make good use of parentheses.   And they’re sometimes necessary!  Consider the following two (almost identical) calls:

get-childitem -recurse -force | where-object { $_.PsIsContainer -eq $true -and $_.Name -eq ".svn" }  | remove-item –recurse –force

(get-childitem -recurse -force | where-object { $_.PsIsContainer -eq $true -and $_.Name -eq ".svn" } ) | remove-item –recurse -force

Very subtle difference: in the second one, I’m combining the pipelined directories obtained by the get-childitem call in parentheses BEFORE I pipeline it to the remove-item cmdlet.  This is the only way it will work properly.  The culprit?  The where-object filter, when left alone without parentheses, won’t pass the right objects to remove-item.  When put in parentheses with get-childitem, however, the where-object doesn’t pipe anything to anybody – it’s just filtering out the GCI data.

Hope this helps.

No Comments

How to Uninstall Windows PowerShell 1.0

Software

Having problems upgrading your old PowerShell 1.0 installation to the 2.0 CTP? The CTP won’t install until you’ve uninstalled all previous versions of PowerShell, but lots of people are having problems figuring out how to uninstall v1.0.

The official docs tell you to click on the “Show updates” checkbox in the Control Panel Add/Remove Programs applet, but that didn’t work for me. “Windows PowerShell 1.0″ (or any variation thereof) didn’t show up.

A google search led me to look for installed service packs in the %WINDOWS%\$NtUninstallKB* directories that has the “PSCustomUtil.exe” file in them. Then go to the child /spuninst/ directory and uninstall the KB that way. I got a ton of warnings saying I would nuke my system back to the Stone Age should I attempt the treasonous act of actually uninstalling a KB patch, but I – being the renegade that I am – went ahead and did it anyway.

My search picked up two KB packs: KB926139-v2 (Windows PowerShell 1.0), and KB926141 (Windows PowerShell MUI).

Once I uninstalled both, I was able to successfully install the PowerShell v2 CTP3.

Hope this helps you too.

10 Comments

PowerShell 2.0 CTP: How to find static members

Software

This one stumped me for a minute – how do you find static members of a given type? Get-Member by default only shows the instance members.

The trick is to use the flag -static with Get-Member, to tell PowerShell that you want only static members.

Example:

[Convert] | gm -static

No Comments
« Older Posts