powershell

    how to rdp to several desktops one after the other

    For reasons that aren’t necessarily relevant, I wanted to use Remote Desktop to visit a list of servers1. I tried doing this:

    foreach ($S in "server01", "server02, "server03") { 
        mstsc /f /V:$S
    }
    

    This works….but it immediately starts rdp sessions to each of the servers. This is fine in this example, where there are only 3 servers, but in real life I’ve got a list of twenty or so and I don’t really want to open 20-odd rdp sessions at once.

    What I did instead to force it do the rdp’s sequentially was this:

    foreach ($S in "server01", "server02, "server03") { 
        mstsc /f /V:$S
        $ThrowAway = read-host "Hit Return"
    }
    

    1. I'd really rather not do this, but I can't find a safe and seen-to-be-safe way of doing what I want to do through PowerShell or any other automated tool 

    how to extract tweets about...

    This was the Powershell code I used to create the all the podcasts I’ve ever tweeted about post.

    I downloaded the tweets from Twitter itself - I think there was a link somewhere within ‘Settings’

    The .csv file looks like this:

    Tweets csv file

    So the code is:

    $PodTweets = Import-Csv c:temptweets.csv | ? text -like "*podcast*"
    
    $TweetsAsHtml = foreach ($P in $PodTweets)
    {
    #   write-output $P.timestamp.Substring(0,10)
    
       # Splitting the tweet text into words to allow for the processing of urls
       $TweetTextAsArray = $P.text.split(" ")
    
       $TextWithLink=""
    
       foreach ($Word in $TweetTextAsArray)
       {
            if ($Word -like "http:*")
            {
                # if there is an expanded_url, then use that instead
                if ($P.expanded_urls -ne "")
                {
                    $Word = $P.expanded_urls
    
                    # for some reason the expanded url is sometimes repeated in the download
                    if ($Word -like "*,*")
                    {
                        $Word = $Word.split(",")[0]
                    }
                }
    
                # re-format the URL as a link
                $Word = "`<a href=`"$Word`"`>$Word`<`/a`>"
            }
            $TextWithLink = "$TextWithLink$Word "
    
    
        }
    
        # create an object and output that
        $properties = @{'TweetDate'=$P.timestamp.Substring(0,10);
                        'TweetText'=$TextWithLink}
    
        $ReformattedTweets = New-Object -Type PSObject -Prop $properties
    
        write-output $ReformattedTweets
    
    }
    
    $TweetsAsHtml | fl | out-file -encoding ascii -FilePath x.txt -width 1000
    

    system databases not included in powershell sqlserver provider 'databases' folder

    I hadn’t noticed this before.

    If you do a dir listing of the databases for an instance within the Powershell Sqlserver provider, it doesn’t show the system databases

    PS C:powershell> dir SQLSERVER:\SQL\my_pcinst2012\databases
    
    Name                 Status          Recovery Model CompatLvl Collation                      Owner
    ----                 ------          -------------- --------- ---------                      -----
    AdventureWorks2012   Normal          Simple               110 SQL_Latin1_General_CP1_CI_AS   matty
    TSQL2012             Normal          Full                 110 Latin1_General_CI_AS           matty
    

    To get a listing for the system databases you can do the following. I would imagine there’s a better way (perhaps some equivalent to ls -a?)…but I can’t think of it at the minute1

    PS C:powershell> foreach ($DB in ("master", "msdb", "model", "tempdb")) {gi SQLSERVER:\SQL\my_pcinst2012\databases\$DB }
    
    Name                 Status          Recovery Model CompatLvl Collation                      Owner
    ----                 ------          -------------- --------- ---------                      -----
    master               Normal          Simple               110 Latin1_General_CI_AS           sa
    msdb                 Normal          Simple               110 Latin1_General_CI_AS           sa
    model                Normal          Simple               110 Latin1_General_CI_AS           sa
    tempdb               Normal          Simple               110 Latin1_General_CI_AS           sa
    

    1. The ‘better way’ is to use gci -force. That includes all the system databases. ↩︎

    Powershell pattern matching to check if a string is hex

    Hexadecimal-counting I’ve been playing with pattern matching in Powershell.

    I was trying to use ‘-match’ to ‘Check if the string is a hexadecimal number’ for the ‘Perl one-liners in Powershell’ page I’ve been working on.

    I can’t pretend to entirely understand or explain pattern matching in Powershell, or in linux, but this seems to work.

    $X = "21e" ; $Y = $X.length ; $X -match "[0123456789abcde]{$Y}"
    

    This says match the string against ‘any combination of the characters within the square brackets (i.e. the hex digits) to the same length as the original string’.

    So, the square brackets contain the allowable characters.

    The curly brackets give the number of characters.

    I tried just doing:

    $X = "21e" ; $X -match "[0123456789abcde]{$X.length}"
    

    …but this didn’t seem to work.

    Tests

    I tried the following strings - they all seemed to come up with the right answer: ``` $ $X = "21e" ; $Y = $X.length ; $X -match "[0123456789abcde]{$Y}" True $ $X = "21edjhsd" ; $Y = $X.length ; $X -match "[0123456789abcde]{$Y}" False $ $X = "21e34782348237847832748723" ; $Y = $X.length ; $X -match "[0123456789abcde]{$Y}" True $ $X = "21e34782348237847832748723f" ; $Y = $X.length ; $X -match "[0123456789abcde]{$Y}" False $ $X = "21e34782348237847832748723acbdaaa" ; $Y = $X.length ; $X -match "[0123456789abcde]{$Y}" True $ $X = " " ; $Y = $X.length ; $X -match "[0123456789abcde]{$Y}" False ```

    ….although I’m not sure whether this is right or wrong:

    $ $X = "" ; $Y = $X.length ; $X -match "[0123456789abcde]{$Y}"
    True
    

    Mis-spelling in Powershell

    This was spectacularly incompetent even by my high standards of incompetence.

    It illustrates that if you spell the name of a column incorrectly in Powershell, you don’t get an error, you just get a null column

    get-wmiobject -class win32_operatingsystem -computer rdm016 |
    select __Server, ServicePackMajorVerstion
    

    And got:

    __SERVER                             ServicePackMajorVerstion
    --------                             ------------------------
    RDM016
    

    I thought that no service packs had been applied. This, as more attentive readers will have spotted, was not the case. The null under ServicePackMajorVerstion is because you don’t spell ‘version’ with a ’t'. Two learnings from this:

    • one should test one’s code
    • if you put something invalid in a ‘select’ list in Powershell it won’t necessarily error

    How to report mp3 tags in Powershell

    I’m slowly getting to grips with Powershell.

    # -----------------------------------------------------------------
    # Script - Catalog-MP3s.ps1 #
    # Gets mp3 tags from the mp3 file.
    # -----------------------------------------------------------------
    # Parameter is either a directory or an individual mp3 Param ( $P_DIR_OR_MP3 )  
    # --------------------------
    # Function: get-mp3info
    # The function gets the tags
    # for the specified mp3
    # --------------------------
    Function get-mp3info ($P_MP3)
    {
         # Get the tages into a variable
         $TAGS = [TagLib.File]::Create("$P_MP3")
         $TAGS_OBJECT = @{Filename = $TAGS.Name;
    
         Bitrate = $TAGS.Properties.AudioBitRate;
         Artist = $TAGS.tag.FirstArtist;
         Title =  $TAGS.tag.Title;
         Genre = $TAGS.tag.FirstGenre;
         LP = $TAGS.tag.Album}
    
         # Output as an object
         New-Object PSObject -Property $TAGS_OBJECT
    }
    
         # --------------------------
         # Main body
         # --------------------------
         # Store the location of the taglib dll
         $TAGLIB="C:\Users\Matt\Downloads\taglib-sharp-2.1.0.0-windows\taglib-sharp-2.1.0.0-windows\Libraries\tag\lib-sharp.dll"
    
         # Load the DLL
         [System.Reflection.Assembly]::LoadFile($Taglib)
    
         # Get a list of all the MP3s under the specified folder
         # - exclude anything that's not an mp3
         # - Fullname contains the full path and filename
         $MP3_LIST = gci -recurse Filesystem::$DIR_OR_MP3 |
                         where {$_.Extension -eq '.mp3'} |
                         select FullName
    
         # Walk through the list, and output the tags
         foreach ($MP3 in $MP3_LIST)
         {
              get-mp3info $MP3.Fullname
         }
    

    The heavily borrows from:

← Newer Posts