How to search output with PowerShell



  • We had a sysadmin (with whom I was never particularly impressed) write a script that deletes cached windows credentials for certain websites using powershell.

    Here's what his code looks like:

    $a = cmdkey /list:cached.site.com
         if ($a -match "cached.site.com") { cmdkey /delete:cached.site.com }
         else { Exit-PSSession }
    

    I was impressed that his script had worked on the first try. But when I went to update it, I noticed it always tried to delete the credentials, regardless of whether they were cached or not. This wasn't a big issue; the script still worked. But it defeated the whole purpose of the if statement. Why did this happen? Let's take a look at the output of cmdkey /list:google.com:

    Currently stored credentials for google.com:
    
    * NONE *
    

    :facepalm:



  • cmd script to implement the same logic, except correctly:

    for /f "tokens=1*" %%A in ('cmdkey /list:cached.site.com') do (
        if "%%A" == "Target:" cmdkey /delete:"%%B"
    )
    

    But how lucky we are to have this shiny new object oriented shell that has finally managed to make the ad-hoc parsing of command text output a thing of the past.



  • Can't they just set an exit status like a normal CLI?



  • Very few Microsoft CLI tools are actually designed to interwork sanely with anything else; cmdkey certainly isn't. I've done quite a lot of scripting on MS platforms, one way or another, and in my experience relying on the exit status for console commands works for about one in four.



  • Yeah, most everything I do as far as scripting things via the Windows CLI involves parsing the output of commands in various ways. Powershell alleviates some of these headaches, however.



  • This reminds me of when I spent hours Googling how to extract a path from the registry in Windows Batch Script file without weird external dependencies. I ended up with this and a headache. I've decided to not mess with Batch since.



  • Yeah, I've done some TR­:wtf: stuff in batch as well. Powershell handles everything a lot better, so I decided to learn it. No regrets.



  • Replace your code with this:

    [code]
    $a = @(cmdkey /list:cached.site.com)
    If ($a[3] -NotMatch '* None *'){cmdkey /delete:cached.site.com}
    [/code]

    Powershell is great by the way. I won't shed a tear for batch or VBS.



  • @YellowOnline said:

    Powershell is great by the way

    Agreed. I just replaced it with the three cmdkey /delete commands as running them without any credentials doesn't hurt anyone.



  • I've used System.Xml.Linq (or was it System.Linq.Xml?) from PowerShell to run arbitrary one-off transformations on a whole shitload of .vxcproj files that I couldn't be bothered to edit by hand...


Log in to reply