Monday, July 29, 2013

PowerShell to Create a random Music Playlist in VLC

This is a trick which got famous at the PowerShell Bangalore User Group (PSBUG) session.

Little trick to play a single random song provided VLC (or any other player) is set as default player for the .mp3 files:

  Posh (0002) >  Get-ChildItem -Path 'F:\songs\movies neew' -Include *.mp3 -Recurse | Get-Random -Count 1 | Invoke-Item 

But this won't create a playlist for you if you simply increased the count for Get-Random..try this
  Posh (0003) >  Get-ChildItem -Path 'F:\songs\movies neew' -Include *.mp3 -Recurse | Get-Random -Count 2 | Invoke-Item


Let's try creating a playlist this time ( have to set VLC as  the default player for .mp3 files , thus creating filetype associations for .mp3 files) 

You need get all the possible list values for mp3 extension.I read this excellent article by David Moravec at PowerShellMagazine to list all possible verb values for a particular extension.
After you go through the above mentioned article, you just use the below code to get a list of all extensions and the list of verbs associated with them

001
002
003
004
005
cmd /c assoc |
ForEach
{
    $ext = ($_ -split '=' )[0 ]"{0}: {1}" -f $ext, (( New-Object System.Diagnostics.ProcessStartInfo -ArgumentList "test$ext" ).Verbs -join ', ' )
}| Out-GridView -Title 'Verb values for associated extensions'

Now on the Out-Gridview window filter out using ".mp3" and see the list of verbs that we have



Now we have all the ingredients ready, First we get a list of all .mp3 files in a directory then randomly get 5 files out of it and at last foreach of those 5 files we start a process with the -verb parameter taking an argument of 'AddtoPlaylistVLC'

001
002
003
004
005
006

 get-childitem -Path 'F:\songs\movies neew' -Filter *.mp3 -Recurse |
    Get-Random -Count 5 |
    Foreach { Start-Process -FilePath $_.Fullname -verb 'AddtoPlaylistVLC' }


Wait and watch :)

Monday, July 15, 2013

using throw inside param() block

Recently I had to write  a very restrictive script which takes few arguments like a filename, computername etc.
These parameters need to be compulsory otherwise the script should not run...

Below is the first function I came up with(nothing fancy):

function Test-AdvancedFunction {
     [CmdletBinding()]
      param(
           [Parameter(Position =0, Mandatory =$true )]
           [ValidateScript({Test-path $_})]
           [ System.String]
            $FileName

     )
     $Name
     ## Normal Script Code goes here
     }

In the above in the param() block a mandatory named argument is specified and has a ValidateScript attribute.

Everything looks great but the function needs to be very restrictive and it should fail when the parameter is not supplied to the function.
Right now because of making the parameter mandatory , I get a prompt to supply the value as below :



But I wanted my function to fail if the parameter is not specified cause I want to run my function non-interactively. 

I knew that the throw statement can be used to achieve this. Below is the info from about_throw topic.

USING THROW TO CREATE A MANDATORY PARAMETER

   You can use the Throw keyword to make a function parameter mandatory.

   This is an alternative to using the Mandatory parameter of the Parameter
   keyword. When you use the Mandatory parameter, the system prompts the user
   for the required parameter value. When you use the Throw keyword, the
   command stops and displays the error record.

So I used the throw statement to achieve what I needed, instead of the Mandatory Named Argument  :)

function Test-AdvancedFunction {
     [CmdletBinding()]
      param(
           [Parameter(Position =0 )]
           [ValidateScript({ Test-path $_})]
           [System.String]
           $FileName = $(throw "Filename not specified")

     )
      $FileName
      ## Normal Script Code goes here
     }


Now I can use validation as well as exit the function when the parameter is not specified  :

So in this way we can have a mandatory parameter which will exit the script/function if the parameter is not supplied while invoking the script/function rather than prompting user for the info.

Sunday, July 07, 2013

Drop to PowerShell using Remotely Anywhere

This is just basics but something I came across recently ,  remotely anywhere is a remote administration tool which our Enterprise uses.
Most of the time User face some issues with installation of applications , so Remotely anywhere helps in assisting them using the remote desktop using a web interface

Remotely anywhere also listens on port 22 the name of the service is "RemotelyAnywhere SSH Server".

Sojust connect to a remote machine using putty and then you are droppped to a  cmd shell  and then start PowerShell from there. The best part is it doesn't prompt for the User confirmation :)


The pre-requisite is that Remotely Anywhere be installed on the remote machine and listening on port 22.

So open up a putty console and connect on port 22.



After that you need to authenticate yourself, I am logging into a machine in Enterprise (running AD) so I used my domain credentials to log in and you do need to


After that you are dropped to a command prompt, from where you can run powershell.exe for swift and easy administration :)





Now the difference between the opened session in the above screenshot is that the Profile gets executed when I open this session which is equivalent to running this powershell session locally on that machine.

Note : When you open a PSSession the profile doesn't run for the User.

So now for common tasks to be performed behind the scene for Users like installing a SCCM client, repairing it can be done without disrupting User's day to day work.