SlideShare a Scribd company logo
1 of 166
An introduction to...




 Windows
PowerShell
Dale Lane

dale.lane@uk.ibm.com
  IBM Hursley Park
Agenda

What is Windows PowerShell?


How does PowerShell work?


How can I 'hack' PowerShell so that
What is
Windows
PowerShell?
What is Windows PowerShell for?
What is Windows PowerShell for?




       ADMIN
What is Windows PowerShell for?

ADMIN
  Building GUIs on
  top of
  PowerShell
What is Windows PowerShell for?

ADMIN
  Interactive
  command shell
What is Windows PowerShell for?

ADMIN
  Scripting
What is Windows PowerShell for?

ADMIN
  COM Scripting
  for WMI
What is Windows PowerShell for?

ADMIN
                        before                       now

 GUI                    MMC                          GUIs built on top of
                                                     PowerShell

 I nt eract ive shell   CMD                          PowerShell

 Script ing             BAT in CMD                   PowerShell

 COM                    WMI (VBScript and JScript)   PowerShell
How does
PowerShell
work?
Get-Process
Get-Process
a verb
         a noun




Get-Process
The verbs




     http://msdn2.microsoft.com/en-us/library/ms714428.aspx
The verbs
  Consistent
    Learnable
       Readable
Get-Process |
Where { $_.Handles -gt 500 } |
  Sort Handles | Format-Table
HELP!
HELP!

Get-Command

Get-Help

Get-PSDrive

Get-Members
What command do I need?
How does it work?
How does it work?
How does it work?
How does it work?
How does it work?
Get-Process |
Where { $_.Handles -gt 500 } |
  Sort Handles | Format-Table




   Consistent
What data stores are available?
Windows Registry
Certificates
Environment variables
Variables
'dir' ?
Aliases
Stopping a process


kill   -9 `ps -aef
   |   grep 'notepad'
   |   grep -v grep
   |   awk '{print $2}'`
Stopping a process


kill   -9 `ps -aef
   |   grep 'notepad'
   |   grep -v grep
   |   awk '{print $2}'`



Why so complicated?
Stopping a process


Get-Process notepad
   | Stop-Process
Stopping a process


Get-Process notepad
   | Stop-Process




Why so much easier?
Sort
  Select

       Where

           Compare
-WhatIf
  -Confirm

     -Verbose

          -Debug
Get-Process | Export-Csv
Using .NET
([xml](new-object Net.WebClient)
           .DownloadString
($bbc_news_rss_url)).rss.channel.item
    | Select title, Desc*, *date
               -first 8
How can I
“hack”
PowerShell?
Why?
“Queue
        Manager”


        “Message”


        “Queue”




WebSphere MQ
a verb
         a noun




Get-Process
http://msdn2.microsoft.com/en-us/library/ms714657.aspx

a verb
          product
           name                        object
                                        type


Get-ProdObject
“Some of the queues used
by the sales team are
getting a bit full. Can you
increase the amount of
space in them?”
“Some of the queues used
by the sales team are
getting a bit full. Can you
increase the amount of
space in them?”

            SALES.*
“Some of the queues used
by the sales team are
getting a bit full. Can you
increase the amount of
space in them?”

 depth > (max depth - 10)
“Some of the queues used
by the sales team are
getting a bit full. Can you
increase the amount of
space in them?”

         double max depth
Get-Command Get-*WMQ*Queue
Get-WMQQueue
Where {$_.Name -like “SALES.*”
             -and
  $_.CurrentDepth -gt
        ($_.MaximumDepth - 10)}
Select Name,
   CurrentDepth,
      MaximumDepth
PS C:> Get-WMQQueue * * | Set-WMQQueue -Description “hacked!”




ForEach-Object -process
 {Set-WMQQueue $_
   -MaximumDepth
     ($_.MaximumDepth * 2)}
ForEach-Object -process
 {Set-WMQQueue $_
   -MaximumDepth
     ($_.MaximumDepth * 2)}
Get-Member
Where {$_.CreationDateTime
 -ge $(Get-Date -month 10 -day 15 -year 2007)
          -and   $_.CreationDateTime
-le $(Get-Date -month 10 -day 20 -year 2007)}
“Set the maximum depth for
all cluster queues that start
with a letter between 'D' and
'K'to 20.”
“Set the maximum depth for
all cluster queues that start
with a letter between 'D' and
'K'to 20.”


   Get-WMQQueue * * | Where
  {$_.Name -like "[D-K]*" -and
    $_.ClusterName -ne ''}
| Set-WMQQueue -MaximumDepth 20
“Set the maximum depth for
all cluster queues that start
with a letter between 'D' and
'K'to 20.”


    Get-WMQQueue * * | Where
  {$_.Name -like "[D-K]*" -and
     $_.ClusterName -ne ''}
   | Set-WMQQueue -MAXDEPTH 20
“Get a list of non-system
sender channels, showing the
name, connection name,
transmission queue, SSL
Cipher Spec, and the name of
the queue manager it is on.”
“Get a list of non-system
   sender channels, showing the
   name, connection name,
   transmission queue, SSL
   Cipher Spec, and the name of
   the queue manager it is on.”
Get-WMQChannel * * | Where {$_.ChannelType -eq [IBM.WMQ.MQC]::MQCHT_SENDER -and $_.Name -match
"^(?!SYSTEM).*"} | Select Name, Conn*Name, Trans*Name, SSLCiph*, @{e={$_.QueueManager.Name};n='Host'}


Name          ConnectionName                  TransmissionQueueName      SSLCipherSpec         Host
----          --------------                  ---------------------      -------------         ----
SECURE        dlane.hursley.ibm.com(9090)     TRANS1                     NULL_MD5              post
SECURE.R      dlane.hursley.ibm.com(9091)     TRANSR                     TRIPLE_DES_SHA_US     test
Export-CSV

ConvertTo-HTML
How?
What can I do with PowerShell?

    Ad-hoc scripts



    Production scripts
What can I do with PowerShell?

    Ad-hoc scripts
       arguments don't need to be named

       arguments don't need to be typed

       scripts don't need to be signed


    Production scripts
       etc.
What can I do with PowerShell?

     Ad-hoc scripts
    arguments can be typed
    rich error handling
    protection against uninitialised variables
    multiple output streams
    scripts digitally signed
    etc.

    Production scripts
What can I do with PowerShell?

   ●   try stuff out in an interactive shell
   ●   tie a few things together in utilities
   ●   build commands up into a script
   ●   generalize (parameterize, etc.)
   ●   clean up and productize
   ●   share!
function Get-WMQQueue ($qmgr)
{
    # display details of any WMQ errors encountered in this function
    Trap [IBM.WMQ.MQException]
    {
        Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode +
                                  " RC=" + $_.Exception.ReasonCode)
        continue
    }

    # if we have a connection to a queue manager...
    if ($qmgr -ne $null)
    {
        $qNames = Get-WMQQueueNames($qmgr)

           foreach ($queuename in $qNames)
           {
               $nextQueue = $qmgr.AccessQueue($queuename.Trim(),
                                              [IBM.WMQ.MQC]::MQOO_INQUIRE)

               Write-Output $nextQueue
           }
    }
    else
    {
           Write-Host "No queue manager connection"
    }



                                                        Ad-hoc
}
function Get-WMQQueue ($qmgr)
{
    # display details of any WMQ errors encountered in this function
    Trap [IBM.WMQ.MQException]
    {
        Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode +
                                  " RC=" + $_.Exception.ReasonCode)
        continue
    }

    # if we have a connection to a queue manager...
    if ($qmgr -ne $null)
    {
        $qNames = Get-WMQQueueNames($qmgr)

           foreach ($queuename in $qNames)
           {
               $nextQueue = $qmgr.AccessQueue($queuename.Trim(),
                                              [IBM.WMQ.MQC]::MQOO_INQUIRE)

               Write-Output $nextQueue
           }
    }
    else
    {
           Write-Host "No queue manager connection"
    }



                                                        Ad-hoc
}
function Get-WMQQueue ($qmgr)
{
    # display details of any WMQ errors encountered in this function
    Trap [IBM.WMQ.MQException]
    {
        Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode +
                                  " RC=" + $_.Exception.ReasonCode)
        continue
    }

    # if we have a connection to a queue manager...
    if ($qmgr -ne $null)
    {
        $qNames = Get-WMQQueueNames($qmgr)

           foreach ($queuename in $qNames)
           {
               $nextQueue = $qmgr.AccessQueue($queuename.Trim(),
                                              [IBM.WMQ.MQC]::MQOO_INQUIRE)

               Write-Output $nextQueue
           }
    }
    else
    {
           Write-Host "No queue manager connection"
    }



                                                        Ad-hoc
}
function Get-WMQQueue ($qmgr)
{
    # display details of any WMQ errors encountered in this function
    Trap [IBM.WMQ.MQException]
    {
        Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode +
                                  " RC=" + $_.Exception.ReasonCode)
        continue
    }

    # if we have a connection to a queue manager...
    if ($qmgr -ne $null)
    {
        $qNames = Get-WMQQueueNames($qmgr)

           foreach ($queuename in $qNames)
           {
               $nextQueue = $qmgr.AccessQueue($queuename.Trim(),
                                              [IBM.WMQ.MQC]::MQOO_INQUIRE)

               Write-Output $nextQueue
           }
    }
    else
    {
           Write-Host "No queue manager connection"
    }



                                                        Ad-hoc
}
function Get-WMQQueueManager($name, $hostname, $port, $svrconn)
{
    # display details of any WMQ errors encountered in this function
    Trap [IBM.WMQ.MQException]
    {
        Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode +
                                  " RC=" + $_.Exception.ReasonCode)
        continue
    }

    # hashtable to describe the connection to the queue manager
    $connProperties = New-Object System.Collections.Hashtable

    if (($hostname -eq $null) -and ($port -eq $null) -and ($svrconn -eq $null))
    {

        # user has not provided any information for a client connection
        # so we default to a local bindings connection type

        $connProperties.Add([string][IBM.WMQ.MQC]::TRANSPORT_PROPERTY,
                            [string][IBM.WMQ.MQC]::TRANSPORT_MQSERIES_BINDINGS)

    }




                                                     Ad-hoc
else
{

   # user has provided some information for a client connection
   #
   # a future version of this should provide support for other
   # connection types (e.g. managed or XA client) but for
   # my initial purposes, bindings and client connections are
   # sufficient

   $connProperties.Add([string][IBM.WMQ.MQC]::TRANSPORT_PROPERTY,
                       [string][IBM.WMQ.MQC]::TRANSPORT_MQSERIES_CLIENT)

   if ($hostname -ne $null)
   {
       $connProperties.Add([string][IBM.WMQ.MQC]::HOST_NAME_PROPERTY,
                           $hostname)
   }




                                                Ad-hoc
if ($svrconn -ne $null)
{
     $connProperties.Add([string][IBM.WMQ.MQC]::CHANNEL_PROPERTY,
                         $svrconn)
}
else
{
     # use a sensible default
     # this wont be to everyone's tastes, but will often be
     # right for me, and will save me a lot of typing!

    $connProperties.Add([string][IBM.WMQ.MQC]::CHANNEL_PROPERTY,
                        "SYSTEM.DEF.SVRCONN")
}




                                              Ad-hoc
if ($port -ne $null)
        {
             $connProperties.Add([string][IBM.WMQ.MQC]::PORT_PROPERTY,
                                 $port)
        }
        else
        {
             # use a sensible default
             # this wont be to everyone's tastes, but will often be
             # right for me, and will save me a lot of typing!

            $connProperties.Add([string][IBM.WMQ.MQC]::PORT_PROPERTY,
                                "1414")
        }
    }

    return New-Object IBM.WMQ.MQQueueManager($name, $connProperties)
}




                                                      Ad-hoc
function Get-WMQQueueNames($qmgr)
{
    # display details of any WMQ errors encountered in this function
    Trap [IBM.WMQ.MQException]
    {
        Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode +
                                   " RC=" + $_.Exception.ReasonCode)
        continue
    }

   # if we have a connection to a queue manager...
   if ($qmgr -ne $null)
   {
       # using PCF to access a list of queue names
       #
       # this is sort of cheating - this is an undocumented, unsupported
       # API, and I wrote this using tab-complete to identify what
       # seems like sensible method names
       #
       # please do *not* take this as any sort of IBM recommendation
       # or endorsement to use PCF in C#
       #
       [IBM.WMQ.PCF.PCFMessageAgent]$agent =
                                 New-Object IBM.WMQ.PCF.PCFMessageAgent
       $agent.Connect($qmgr)




                                                      Ad-hoc
[IBM.WMQ.PCF.PCFMessage]$request =
        New-Object IBM.WMQ.PCF.PCFMessage([IBM.WMQ.MQC]::MQCMD_INQUIRE_Q_NAMES)

       $request.AddParameter([IBM.WMQ.MQC]::MQCA_Q_NAME,
                           "*")
       $request.AddParameter([IBM.WMQ.MQC]::MQIA_Q_TYPE,
                           [IBM.WMQ.MQC]::MQQT_LOCAL)

       [IBM.WMQ.PCF.PCFMessage[]]$responses = $agent.Send($request, $TRUE)
       [IBM.WMQ.PCF.PCFParameter[]]$pcfParms = $responses[0].GetParameters()

       $queueNames = $pcfParms[0].GetValue()

       # we don't want to display temporary queues
       # (such as that which will have been created by the PCF command!)
       # so we filter the response array before returning it
       return $queueNames | Where-Object -FilterScript {$_ -notlike "AMQ.*"}
    }
    else
    {
        Write-Host "No queue manager"
    }
}




                                                     Ad-hoc
PS C:> Get-WMQQueue (Get-WMQQueueManager test) | Select Name, CurrentDepth

Name                                                    CurrentDepth
----                                                    ------------
DALE                                                               0
SALES.1                                                            1
SALES.2                                                           15
SALES.3                                                            9
SALES.4                                                            1
SALES.5                                                            4
SALES.6                                                            2
SYSTEM.ADMIN.ACCOUNTING.QUEUE                                      0
SYSTEM.ADMIN.ACTIVITY.QUEUE                                        0
SYSTEM.ADMIN.CHANNEL.EVENT                                         0
SYSTEM.ADMIN.COMMAND.QUEUE                                         0
SYSTEM.ADMIN.LOGGER.EVENT                                          0
SYSTEM.ADMIN.PERFM.EVENT                                           0
SYSTEM.ADMIN.QMGR.EVENT                                            1
SYSTEM.ADMIN.STATISTICS.QUEUE                                      0
SYSTEM.ADMIN.TRACE.ROUTE.QUEUE                                     0
SYSTEM.AUTH.DATA.QUEUE                                            61
SYSTEM.CHANNEL.INITQ                                               0
SYSTEM.CHANNEL.SYNCQ                                               0
SYSTEM.CICS.INITIATION.QUEUE                                       0
SYSTEM.CLUSTER.COMMAND.QUEUE                                       0



                                                  Ad-hoc
http://channel9.msdn.com/ShowPost.aspx?PostID=256835




             Production
“How to Create a Windows PowerShell Cmdlet”
    walkthrough

 http://msdn2.microsoft.com/en-us/library/ms714598.aspx




                           Production
“How to Create a Windows PowerShell Cmdlet”
    walkthrough

 http://msdn2.microsoft.com/en-us/library/ms714598.aspx



“PowerShell Cmdlet guidelines”

 http://msdn2.microsoft.com/en-us/library/ms714657.aspx




                           Production
#region GetProcCommand

/// <summary>
/// This class implements a Get-Proc cmdlet that has no parameters.
/// </summary>

[Cmdlet(VerbsCommon.Get, "Proc")]
public class GetProcCommand : Cmdlet
{
  #region Cmdlet Overrides
  /// <summary>
  /// For each of the requested process names, retrieve and write
  /// the associated processes.
  /// </summary>

  protected override void ProcessRecord()
  {
    // Get the current processes
    Process[] processes = Process.GetProcesses();

    // Write the processes to the pipeline making them available to the
    // next cmdlet. The second parameter tells PowerShell to enumerate the
    // array, and send one process at a time to the pipeline
    WriteObject(processes, true);
  }
  #endregion Overrides

}


                                    Production
#endregion GetProcCommand
Production
Production
PS C:> Add-PSSnapin WebSphereMQ




                                   Production
What can I do with PowerShell?

   ●   try stuff out in an interactive shell
   ●   tie a few things together in utilities
   ●   build commands up into a script
   ●   generalize (parameterize, etc.)
   ●   clean up and productize
   ●   share!
Extending PowerShell

Extending function
    --> scripts and Cmdlets

Extending data stores
    --> providers
Recap

What is Windows PowerShell?


How does PowerShell work?


How can I hack PowerShell so that
Dale Lane

dale.lane@uk.ibm.com
  IBM Hursley Park


        An introduction to...


           Windows
          PowerShell

More Related Content

What's hot

Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010
Ismael Celis
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwr
deimos
 
Powershell Tech Ed2009
Powershell Tech Ed2009Powershell Tech Ed2009
Powershell Tech Ed2009
rsnarayanan
 
Gearman jobqueue
Gearman jobqueueGearman jobqueue
Gearman jobqueue
Magento Dev
 

What's hot (20)

Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010
 
PowerShell Technical Overview
PowerShell Technical OverviewPowerShell Technical Overview
PowerShell Technical Overview
 
Hopping in clouds: a tale of migration from one cloud provider to another
Hopping in clouds: a tale of migration from one cloud provider to anotherHopping in clouds: a tale of migration from one cloud provider to another
Hopping in clouds: a tale of migration from one cloud provider to another
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalability
 
I Can't Believe It's Not Flash
I Can't Believe It's Not FlashI Can't Believe It's Not Flash
I Can't Believe It's Not Flash
 
Yavorsky
YavorskyYavorsky
Yavorsky
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwr
 
фабрика Blockly
фабрика Blocklyфабрика Blockly
фабрика Blockly
 
Powershell Tech Ed2009
Powershell Tech Ed2009Powershell Tech Ed2009
Powershell Tech Ed2009
 
Super Advanced Python –act1
Super Advanced Python –act1Super Advanced Python –act1
Super Advanced Python –act1
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Into the ZF2 Service Manager
Into the ZF2 Service ManagerInto the ZF2 Service Manager
Into the ZF2 Service Manager
 
Node.js in action
Node.js in actionNode.js in action
Node.js in action
 
Clojure@Nuday
Clojure@NudayClojure@Nuday
Clojure@Nuday
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
Static Typing in Vault
Static Typing in VaultStatic Typing in Vault
Static Typing in Vault
 
Cutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQueryCutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQuery
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
 
Gearman jobqueue
Gearman jobqueueGearman jobqueue
Gearman jobqueue
 
Not your Grandma's XQuery
Not your Grandma's XQueryNot your Grandma's XQuery
Not your Grandma's XQuery
 

Viewers also liked

ABC Breakfast Club m DanZafe: Effektiv lageroprydning
ABC Breakfast Club m DanZafe: Effektiv lageroprydningABC Breakfast Club m DanZafe: Effektiv lageroprydning
ABC Breakfast Club m DanZafe: Effektiv lageroprydning
ABC Softwork
 
Bridal sarees online
Bridal sarees onlineBridal sarees online
Bridal sarees online
ChrisPerez
 
Alaa-Mattar-TOC
Alaa-Mattar-TOCAlaa-Mattar-TOC
Alaa-Mattar-TOC
alaamattar
 

Viewers also liked (16)

ABC Breakfast Club m DanZafe: Effektiv lageroprydning
ABC Breakfast Club m DanZafe: Effektiv lageroprydningABC Breakfast Club m DanZafe: Effektiv lageroprydning
ABC Breakfast Club m DanZafe: Effektiv lageroprydning
 
Once Source to Rule Them All
Once Source to Rule Them AllOnce Source to Rule Them All
Once Source to Rule Them All
 
Bridal sarees online
Bridal sarees onlineBridal sarees online
Bridal sarees online
 
Global
GlobalGlobal
Global
 
Mohamed Attia C.V
Mohamed Attia C.VMohamed Attia C.V
Mohamed Attia C.V
 
Imenco Offshore Helicopter refuelling system presentation
Imenco Offshore Helicopter refuelling system presentationImenco Offshore Helicopter refuelling system presentation
Imenco Offshore Helicopter refuelling system presentation
 
Andrew workman
Andrew workman Andrew workman
Andrew workman
 
Process Flowchart
Process FlowchartProcess Flowchart
Process Flowchart
 
03 10 Broddmagasinet
03 10 Broddmagasinet03 10 Broddmagasinet
03 10 Broddmagasinet
 
CASBAA 1030408 @ Taipei
CASBAA 1030408 @ TaipeiCASBAA 1030408 @ Taipei
CASBAA 1030408 @ Taipei
 
Whitepaper-Business Intelligence- empowering business
Whitepaper-Business Intelligence- empowering businessWhitepaper-Business Intelligence- empowering business
Whitepaper-Business Intelligence- empowering business
 
Summer camp 2015 3М
Summer camp 2015 3МSummer camp 2015 3М
Summer camp 2015 3М
 
Manaus ponta negra
Manaus ponta negraManaus ponta negra
Manaus ponta negra
 
invest4arab.org
invest4arab.orginvest4arab.org
invest4arab.org
 
Accommodations
AccommodationsAccommodations
Accommodations
 
Alaa-Mattar-TOC
Alaa-Mattar-TOCAlaa-Mattar-TOC
Alaa-Mattar-TOC
 

Similar to An introduction-to-windows-powershell-1193007253563204-3

VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
Taha Shakeel
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
Wesley Beary
 
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
buildacloud
 

Similar to An introduction-to-windows-powershell-1193007253563204-3 (20)

WMQ Toolbox: 20 Scripts, One-liners, & Utilities for UNIX & Windows
WMQ Toolbox: 20 Scripts, One-liners, & Utilities for UNIX & Windows WMQ Toolbox: 20 Scripts, One-liners, & Utilities for UNIX & Windows
WMQ Toolbox: 20 Scripts, One-liners, & Utilities for UNIX & Windows
 
Node lt
Node ltNode lt
Node lt
 
Win32 Perl Wmi
Win32 Perl WmiWin32 Perl Wmi
Win32 Perl Wmi
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
 
Exchange 2010/2013 Exchange Management Shell Command
Exchange 2010/2013 Exchange Management Shell CommandExchange 2010/2013 Exchange Management Shell Command
Exchange 2010/2013 Exchange Management Shell Command
 
TDC2018SP | Trilha Go - Processando analise genetica em background com Go
TDC2018SP | Trilha Go - Processando analise genetica em background com GoTDC2018SP | Trilha Go - Processando analise genetica em background com Go
TDC2018SP | Trilha Go - Processando analise genetica em background com Go
 
Introduction To Managing VMware With PowerShell
Introduction To Managing VMware With PowerShellIntroduction To Managing VMware With PowerShell
Introduction To Managing VMware With PowerShell
 
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloud
 
Test driven infrastructure
Test driven infrastructureTest driven infrastructure
Test driven infrastructure
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message Queue
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
 
Building cloud stack at scale
Building cloud stack at scaleBuilding cloud stack at scale
Building cloud stack at scale
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Windows Server 2008 (PowerShell Scripting Uygulamaları)
Windows Server 2008 (PowerShell Scripting Uygulamaları)Windows Server 2008 (PowerShell Scripting Uygulamaları)
Windows Server 2008 (PowerShell Scripting Uygulamaları)
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETFuture Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NET
 
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
 
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
 
KSQL - Stream Processing simplified!
KSQL - Stream Processing simplified!KSQL - Stream Processing simplified!
KSQL - Stream Processing simplified!
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 

An introduction-to-windows-powershell-1193007253563204-3

  • 1. An introduction to... Windows PowerShell
  • 3. Agenda What is Windows PowerShell? How does PowerShell work? How can I 'hack' PowerShell so that
  • 5. What is Windows PowerShell for?
  • 6. What is Windows PowerShell for? ADMIN
  • 7. What is Windows PowerShell for? ADMIN Building GUIs on top of PowerShell
  • 8. What is Windows PowerShell for? ADMIN Interactive command shell
  • 9. What is Windows PowerShell for? ADMIN Scripting
  • 10. What is Windows PowerShell for? ADMIN COM Scripting for WMI
  • 11. What is Windows PowerShell for? ADMIN before now GUI MMC GUIs built on top of PowerShell I nt eract ive shell CMD PowerShell Script ing BAT in CMD PowerShell COM WMI (VBScript and JScript) PowerShell
  • 13.
  • 14.
  • 17. a verb a noun Get-Process
  • 18. The verbs http://msdn2.microsoft.com/en-us/library/ms714428.aspx
  • 19. The verbs Consistent Learnable Readable
  • 20.
  • 21. Get-Process | Where { $_.Handles -gt 500 } | Sort Handles | Format-Table
  • 22. HELP!
  • 24.
  • 25. What command do I need?
  • 26.
  • 27. How does it work?
  • 28. How does it work?
  • 29. How does it work?
  • 30. How does it work?
  • 31. How does it work?
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39. Get-Process | Where { $_.Handles -gt 500 } | Sort Handles | Format-Table Consistent
  • 40.
  • 41. What data stores are available?
  • 42.
  • 44.
  • 46.
  • 48.
  • 51.
  • 53.
  • 54.
  • 55. Stopping a process kill -9 `ps -aef | grep 'notepad' | grep -v grep | awk '{print $2}'`
  • 56. Stopping a process kill -9 `ps -aef | grep 'notepad' | grep -v grep | awk '{print $2}'` Why so complicated?
  • 57. Stopping a process Get-Process notepad | Stop-Process
  • 58. Stopping a process Get-Process notepad | Stop-Process Why so much easier?
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68. Sort Select Where Compare
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77. -WhatIf -Confirm -Verbose -Debug
  • 78.
  • 79.
  • 80.
  • 81.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99. ([xml](new-object Net.WebClient) .DownloadString ($bbc_news_rss_url)).rss.channel.item | Select title, Desc*, *date -first 8
  • 100.
  • 101.
  • 102.
  • 104. Why?
  • 105. “Queue Manager” “Message” “Queue” WebSphere MQ
  • 106.
  • 107. a verb a noun Get-Process
  • 108. http://msdn2.microsoft.com/en-us/library/ms714657.aspx a verb product name object type Get-ProdObject
  • 109.
  • 110.
  • 111. “Some of the queues used by the sales team are getting a bit full. Can you increase the amount of space in them?”
  • 112. “Some of the queues used by the sales team are getting a bit full. Can you increase the amount of space in them?” SALES.*
  • 113. “Some of the queues used by the sales team are getting a bit full. Can you increase the amount of space in them?” depth > (max depth - 10)
  • 114. “Some of the queues used by the sales team are getting a bit full. Can you increase the amount of space in them?” double max depth
  • 115.
  • 118. Where {$_.Name -like “SALES.*” -and $_.CurrentDepth -gt ($_.MaximumDepth - 10)}
  • 119. Select Name, CurrentDepth, MaximumDepth
  • 120.
  • 121.
  • 122. PS C:> Get-WMQQueue * * | Set-WMQQueue -Description “hacked!” ForEach-Object -process {Set-WMQQueue $_ -MaximumDepth ($_.MaximumDepth * 2)}
  • 123. ForEach-Object -process {Set-WMQQueue $_ -MaximumDepth ($_.MaximumDepth * 2)}
  • 124.
  • 125.
  • 127.
  • 128.
  • 129. Where {$_.CreationDateTime -ge $(Get-Date -month 10 -day 15 -year 2007) -and $_.CreationDateTime -le $(Get-Date -month 10 -day 20 -year 2007)}
  • 130. “Set the maximum depth for all cluster queues that start with a letter between 'D' and 'K'to 20.”
  • 131. “Set the maximum depth for all cluster queues that start with a letter between 'D' and 'K'to 20.” Get-WMQQueue * * | Where {$_.Name -like "[D-K]*" -and $_.ClusterName -ne ''} | Set-WMQQueue -MaximumDepth 20
  • 132. “Set the maximum depth for all cluster queues that start with a letter between 'D' and 'K'to 20.” Get-WMQQueue * * | Where {$_.Name -like "[D-K]*" -and $_.ClusterName -ne ''} | Set-WMQQueue -MAXDEPTH 20
  • 133. “Get a list of non-system sender channels, showing the name, connection name, transmission queue, SSL Cipher Spec, and the name of the queue manager it is on.”
  • 134. “Get a list of non-system sender channels, showing the name, connection name, transmission queue, SSL Cipher Spec, and the name of the queue manager it is on.” Get-WMQChannel * * | Where {$_.ChannelType -eq [IBM.WMQ.MQC]::MQCHT_SENDER -and $_.Name -match "^(?!SYSTEM).*"} | Select Name, Conn*Name, Trans*Name, SSLCiph*, @{e={$_.QueueManager.Name};n='Host'} Name ConnectionName TransmissionQueueName SSLCipherSpec Host ---- -------------- --------------------- ------------- ---- SECURE dlane.hursley.ibm.com(9090) TRANS1 NULL_MD5 post SECURE.R dlane.hursley.ibm.com(9091) TRANSR TRIPLE_DES_SHA_US test
  • 136. How?
  • 137.
  • 138. What can I do with PowerShell? Ad-hoc scripts Production scripts
  • 139. What can I do with PowerShell? Ad-hoc scripts arguments don't need to be named arguments don't need to be typed scripts don't need to be signed Production scripts etc.
  • 140. What can I do with PowerShell? Ad-hoc scripts arguments can be typed rich error handling protection against uninitialised variables multiple output streams scripts digitally signed etc. Production scripts
  • 141. What can I do with PowerShell? ● try stuff out in an interactive shell ● tie a few things together in utilities ● build commands up into a script ● generalize (parameterize, etc.) ● clean up and productize ● share!
  • 142. function Get-WMQQueue ($qmgr) { # display details of any WMQ errors encountered in this function Trap [IBM.WMQ.MQException] { Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode + " RC=" + $_.Exception.ReasonCode) continue } # if we have a connection to a queue manager... if ($qmgr -ne $null) { $qNames = Get-WMQQueueNames($qmgr) foreach ($queuename in $qNames) { $nextQueue = $qmgr.AccessQueue($queuename.Trim(), [IBM.WMQ.MQC]::MQOO_INQUIRE) Write-Output $nextQueue } } else { Write-Host "No queue manager connection" } Ad-hoc }
  • 143. function Get-WMQQueue ($qmgr) { # display details of any WMQ errors encountered in this function Trap [IBM.WMQ.MQException] { Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode + " RC=" + $_.Exception.ReasonCode) continue } # if we have a connection to a queue manager... if ($qmgr -ne $null) { $qNames = Get-WMQQueueNames($qmgr) foreach ($queuename in $qNames) { $nextQueue = $qmgr.AccessQueue($queuename.Trim(), [IBM.WMQ.MQC]::MQOO_INQUIRE) Write-Output $nextQueue } } else { Write-Host "No queue manager connection" } Ad-hoc }
  • 144. function Get-WMQQueue ($qmgr) { # display details of any WMQ errors encountered in this function Trap [IBM.WMQ.MQException] { Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode + " RC=" + $_.Exception.ReasonCode) continue } # if we have a connection to a queue manager... if ($qmgr -ne $null) { $qNames = Get-WMQQueueNames($qmgr) foreach ($queuename in $qNames) { $nextQueue = $qmgr.AccessQueue($queuename.Trim(), [IBM.WMQ.MQC]::MQOO_INQUIRE) Write-Output $nextQueue } } else { Write-Host "No queue manager connection" } Ad-hoc }
  • 145. function Get-WMQQueue ($qmgr) { # display details of any WMQ errors encountered in this function Trap [IBM.WMQ.MQException] { Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode + " RC=" + $_.Exception.ReasonCode) continue } # if we have a connection to a queue manager... if ($qmgr -ne $null) { $qNames = Get-WMQQueueNames($qmgr) foreach ($queuename in $qNames) { $nextQueue = $qmgr.AccessQueue($queuename.Trim(), [IBM.WMQ.MQC]::MQOO_INQUIRE) Write-Output $nextQueue } } else { Write-Host "No queue manager connection" } Ad-hoc }
  • 146. function Get-WMQQueueManager($name, $hostname, $port, $svrconn) { # display details of any WMQ errors encountered in this function Trap [IBM.WMQ.MQException] { Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode + " RC=" + $_.Exception.ReasonCode) continue } # hashtable to describe the connection to the queue manager $connProperties = New-Object System.Collections.Hashtable if (($hostname -eq $null) -and ($port -eq $null) -and ($svrconn -eq $null)) { # user has not provided any information for a client connection # so we default to a local bindings connection type $connProperties.Add([string][IBM.WMQ.MQC]::TRANSPORT_PROPERTY, [string][IBM.WMQ.MQC]::TRANSPORT_MQSERIES_BINDINGS) } Ad-hoc
  • 147. else { # user has provided some information for a client connection # # a future version of this should provide support for other # connection types (e.g. managed or XA client) but for # my initial purposes, bindings and client connections are # sufficient $connProperties.Add([string][IBM.WMQ.MQC]::TRANSPORT_PROPERTY, [string][IBM.WMQ.MQC]::TRANSPORT_MQSERIES_CLIENT) if ($hostname -ne $null) { $connProperties.Add([string][IBM.WMQ.MQC]::HOST_NAME_PROPERTY, $hostname) } Ad-hoc
  • 148. if ($svrconn -ne $null) { $connProperties.Add([string][IBM.WMQ.MQC]::CHANNEL_PROPERTY, $svrconn) } else { # use a sensible default # this wont be to everyone's tastes, but will often be # right for me, and will save me a lot of typing! $connProperties.Add([string][IBM.WMQ.MQC]::CHANNEL_PROPERTY, "SYSTEM.DEF.SVRCONN") } Ad-hoc
  • 149. if ($port -ne $null) { $connProperties.Add([string][IBM.WMQ.MQC]::PORT_PROPERTY, $port) } else { # use a sensible default # this wont be to everyone's tastes, but will often be # right for me, and will save me a lot of typing! $connProperties.Add([string][IBM.WMQ.MQC]::PORT_PROPERTY, "1414") } } return New-Object IBM.WMQ.MQQueueManager($name, $connProperties) } Ad-hoc
  • 150. function Get-WMQQueueNames($qmgr) { # display details of any WMQ errors encountered in this function Trap [IBM.WMQ.MQException] { Write-Error ("WMQ Exception: CC=" + $_.Exception.CompletionCode + " RC=" + $_.Exception.ReasonCode) continue } # if we have a connection to a queue manager... if ($qmgr -ne $null) { # using PCF to access a list of queue names # # this is sort of cheating - this is an undocumented, unsupported # API, and I wrote this using tab-complete to identify what # seems like sensible method names # # please do *not* take this as any sort of IBM recommendation # or endorsement to use PCF in C# # [IBM.WMQ.PCF.PCFMessageAgent]$agent = New-Object IBM.WMQ.PCF.PCFMessageAgent $agent.Connect($qmgr) Ad-hoc
  • 151. [IBM.WMQ.PCF.PCFMessage]$request = New-Object IBM.WMQ.PCF.PCFMessage([IBM.WMQ.MQC]::MQCMD_INQUIRE_Q_NAMES) $request.AddParameter([IBM.WMQ.MQC]::MQCA_Q_NAME, "*") $request.AddParameter([IBM.WMQ.MQC]::MQIA_Q_TYPE, [IBM.WMQ.MQC]::MQQT_LOCAL) [IBM.WMQ.PCF.PCFMessage[]]$responses = $agent.Send($request, $TRUE) [IBM.WMQ.PCF.PCFParameter[]]$pcfParms = $responses[0].GetParameters() $queueNames = $pcfParms[0].GetValue() # we don't want to display temporary queues # (such as that which will have been created by the PCF command!) # so we filter the response array before returning it return $queueNames | Where-Object -FilterScript {$_ -notlike "AMQ.*"} } else { Write-Host "No queue manager" } } Ad-hoc
  • 152. PS C:> Get-WMQQueue (Get-WMQQueueManager test) | Select Name, CurrentDepth Name CurrentDepth ---- ------------ DALE 0 SALES.1 1 SALES.2 15 SALES.3 9 SALES.4 1 SALES.5 4 SALES.6 2 SYSTEM.ADMIN.ACCOUNTING.QUEUE 0 SYSTEM.ADMIN.ACTIVITY.QUEUE 0 SYSTEM.ADMIN.CHANNEL.EVENT 0 SYSTEM.ADMIN.COMMAND.QUEUE 0 SYSTEM.ADMIN.LOGGER.EVENT 0 SYSTEM.ADMIN.PERFM.EVENT 0 SYSTEM.ADMIN.QMGR.EVENT 1 SYSTEM.ADMIN.STATISTICS.QUEUE 0 SYSTEM.ADMIN.TRACE.ROUTE.QUEUE 0 SYSTEM.AUTH.DATA.QUEUE 61 SYSTEM.CHANNEL.INITQ 0 SYSTEM.CHANNEL.SYNCQ 0 SYSTEM.CICS.INITIATION.QUEUE 0 SYSTEM.CLUSTER.COMMAND.QUEUE 0 Ad-hoc
  • 154. “How to Create a Windows PowerShell Cmdlet” walkthrough http://msdn2.microsoft.com/en-us/library/ms714598.aspx Production
  • 155. “How to Create a Windows PowerShell Cmdlet” walkthrough http://msdn2.microsoft.com/en-us/library/ms714598.aspx “PowerShell Cmdlet guidelines” http://msdn2.microsoft.com/en-us/library/ms714657.aspx Production
  • 156. #region GetProcCommand /// <summary> /// This class implements a Get-Proc cmdlet that has no parameters. /// </summary> [Cmdlet(VerbsCommon.Get, "Proc")] public class GetProcCommand : Cmdlet { #region Cmdlet Overrides /// <summary> /// For each of the requested process names, retrieve and write /// the associated processes. /// </summary> protected override void ProcessRecord() { // Get the current processes Process[] processes = Process.GetProcesses(); // Write the processes to the pipeline making them available to the // next cmdlet. The second parameter tells PowerShell to enumerate the // array, and send one process at a time to the pipeline WriteObject(processes, true); } #endregion Overrides } Production #endregion GetProcCommand
  • 159. PS C:> Add-PSSnapin WebSphereMQ Production
  • 160. What can I do with PowerShell? ● try stuff out in an interactive shell ● tie a few things together in utilities ● build commands up into a script ● generalize (parameterize, etc.) ● clean up and productize ● share!
  • 161.
  • 162.
  • 163. Extending PowerShell Extending function --> scripts and Cmdlets Extending data stores --> providers
  • 164.
  • 165. Recap What is Windows PowerShell? How does PowerShell work? How can I hack PowerShell so that
  • 166. Dale Lane dale.lane@uk.ibm.com IBM Hursley Park An introduction to... Windows PowerShell

Editor's Notes

  1. Two quick disclaimers before we get started. One - it&apos;s worth pointing out that I don&apos;t represent Microsoft, or PowerShell. I&apos;m in no way an authority on it – and am speaking from the perspective of a user and a developer. It&apos;s entirely possible that some or all of this presentation may completely misrepresent PowerShell. I don&apos;t think it does, but it might. :-) Or in other words, any mistakes are entirely my own. Any brilliant flashes of insight have been stolen from others (such as some good demo&apos;s of PowerShell by the architect, Jeffrey Snover, which I found on channel9.msdn.com). Two – a lot of what I&apos;m gonna say that I like about PowerShell has been done before. Without spoiling any surprises... bash does command tab-completion, AS400 does consistent command syntax and parameter parsing, and so on. It&apos;s interesting to note historical background, but as I&apos;ve yet to present on PowerShell without someone pointing this out like it&apos;s a bad thing, let me preempt that by saying that I don&apos;t care. Why not borrow/steal from the best you can find and improve on it?
  2. In this presentation, I will give an introduction to what PowerShell is, and how it works. I will then look at how you can extend PowerShell to provide support for administering third-party applications. (The slide says &apos;hack&apos; because this presentation was originally written for HackDay, so I figured &apos;hack&apos; was more in-keeping with the spirit of the day than &apos;extend&apos;).
  3. So – let&apos;s start with the basics. What is PowerShell?
  4. Perhaps the best question for anything new is to ask what it is for? What problem has it been created to solve?
  5. Admin It&apos;s essentially a tool for system administrators.
  6. It&apos;s a platform that you can build rich graphical user interfaces on top of. For example, the new management console for Exchange 2007 is a PowerShell GUI. (And there it is. Pretty, eh?)
  7. It&apos;s an interactive command shell.
  8. It&apos;s a scripting language
  9. It&apos;s also a COM scripting environment, for accessing WMI data.
  10. PowerShell is a single tool / language / environment to do what you might have needed to learn a few different tools or languages to do before. This slide shows the progression if you consider PowerShell as an evolution from existing Windows technologies. Instead of writing custom MMC snap-ins, you can now create an MMC interface on top of a PowerShell admin layer. Instead of the old Windows &apos;Command Prompt&apos;, PowerShell is a new more powerful interactive shell. PowerShell scripts are a way to do more than you could in batch files. And PowerShell scripts can do the WMI work we used to do with VBScript or JScript.
  11. That&apos;s enough scene-setting for now... let&apos;s take a look at PowerShell itself.
  12. And here we go. This is PowerShell.
  13. And here is my PowerShell window after I&apos;ve run my first command to get a list of processes running on my system. The command is (imaginatively titled):
  14. Get-Process
  15. It&apos;s worth highlighting that all of the PowerShell commands (called “cmdlets” but we&apos;ll come back to that in a minute) look like this.
  16. Verb, followed by noun What do you want to do? followed by What do you want to do that to?
  17. There is a standardized set of verbs (and this is just a part of the full list). For example, to get a list of running processes, I used “GET”. Not “read”, “list”, “display”, “find”, etc. It&apos;s “GET”. It&apos;s always “GET”. Whatever you&apos;re doing, whatever system or application you&apos;re administering, in PowerShell, the verb to get elements in a resource is always “GET”.
  18. This is nice – it makes for a more consistent experience. If you move from product to product, you don&apos;t need to learn different commands. Once you learn the core command set – which I found I picked up surprisingly quickly – the learning curve for new commands is significantly reduced. It means you can normally guess what the command will be called. The command names are quite verbose – which makes for very readable scripts. As someone who used to work with other people&apos;s perl scripts, I know what a nightmare it can be deciphering the idea behind a script!
  19. For example... a simple command to get a subset of running processes:
  20. Ignoring some of the syntax quirks for the moment (which we will come back to), this is a very readable command. You can work out what this is doing at a glance.
  21. Not convinced? Okay, so perhaps that command was a little scary for a first example. Let&apos;s take a step back and look at how we can find our way around the PowerShell commands.
  22. There are four basic &apos;help&apos; commands in PowerShell.
  23. The first one Get-Command
  24. Get-Command helps you find which command you need. So I know that I want to get a list of processes... I figure that the command will probably have “process” somewhere in the name, so &apos;Get-Command&apos; for something-process gets me a couple of options. The fact that I know what the verbs all mean meant that I could have probably guessed that it would have started with “Get-”. (To be honest, the fact that commands all support tab-completion means that I could have worked out this command without Get-Command, but you get the idea)
  25. Next – you know what command you need. But how do you find out how to use it? Get-Help
  26. Get-Help followed by the name of any command gives you man-page style help for it. You can see here that I get a nice synopsis, syntax guide and description for the command. And notice that it&apos;s a not an epic tome that scrolls page after page. It&apos;s about getting you going quickly, or jogging your memory. Need more?
  27. Here is some more help for the same command – and this one does scroll for a bit.. this is just the first page.
  28. You get this by adding -detailed to get more detailed documentation
  29. This includes a more detailed description about each of the parameters – what they are for, what type they are, and so on.
  30. It also gives you a bunch of examples. If you&apos;re new to any command in PowerShell, just type &apos;Get-Help&apos;, the name of the command, and &apos;-detailed&apos; and you can get a bunch of examples of how to use it.
  31. Still not enough? There is more if you need it.
  32. This is the &apos;full&apos; documentation. And it goes on for page after page.
  33. You don&apos;t often need this much as a user, but it&apos;s great if you&apos;re a developer using the commands as an API, because it gives you the API documentation. For each parameter, it&apos;ll tell you if it is required, whether it&apos;s positional, the default values, etc.
  34. As well as command documentation, &apos;Get-Help&apos; can also give more general help.
  35. This is called &apos;topic help&apos;, and there is topic help about most of the concepts in PowerShell. Again, this help includes samples and examples.
  36. For example, if you need to write a regular expression and can&apos;t remember your wildcard syntax, about_wildcard is a quick way to get help on what you need.
  37. While I&apos;m mentioning wildcards, as a quick aside, it&apos;s worth pointing out that the wildcard support in PowerShell is fantastic. You can put wildcards anywhere. In commands, in parameters, anywhere. In this command, I&apos;m getting a listing of the contents of the &apos;desktop&apos; directories for all users.
  38. The consistency of the command set is more than just the fact that the names of the commands are consistent. Their behaviour is similar, too. If you want to sort the output from a command, you pipe it to &apos;Sort&apos;. Whereas the UNIX equivalent to Get-Process, &apos;ps&apos; has sort options, Get-Process doesn&apos;t. Other UNIX commands have their own implementations of sort, with their own approach to parameters. But in PowerShell, sort is always sort. It always works the same way, and always needs the same arguments (that is, which property to sort by, and which direction to sort in). This consistency is a common theme in PowerShell. The shell does the command argument parsing – giving the arguments to the individual commands as tokens. So you don&apos;t get some commands starting arguments with a hypen, others starting arguments with a slash, others with nothing and so on. PowerShell has it&apos;s standard way of handling arguments. I mentioned before that PowerShell commands are called “cmdlets”. They are small commands. They don&apos;t do much. That&apos;s the idea – Get-Process doesn&apos;t need to know how to do sorting – it just gets a list of a processes. This consistency is better for the user. (And makes life easier when you&apos;re developing new commands, as the Shell does most of your work for you!)
  39. Okay, so I&apos;ve veered off-topic a bit. Where were we? Help – we&apos;ve got &apos;Get-Command&apos; to figure out which command we want, and &apos;Get-Help&apos; to figure out how it works. Next – &apos;Get-PSDrive&apos;
  40. This gets you a list of data sources that PowerShell knows about. The point is, PowerShell is not just for files and filesystems. You can use it for tons of stuff. And again, consistency is the key – it works the same way whatever data store you are in.
  41. Let&apos;s take a look at the registry on my system.
  42. I love that I can interact with the registry at the command-line now, without needing to resort to regedit. &apos;cd&apos; to change keys, and &apos;dir&apos; to get the contents. It feels like being in a filesystem. (and by the way, tab-completion is particularly helpful here!) And you can do all of the sort of recursive searching and listing that you&apos;d expect. Navigating is all very easy.
  43. What about certificates?
  44. Same sort of thing. You use &apos;cd&apos; and &apos;dir&apos; to navigate and list the contents of the certificate store on your system.
  45. Here are the environment variables for my system
  46. Same sort of behaviour You &apos;cd&apos; to the env store, and can view, search and edit the variables.
  47. PowerShell also has it&apos;s own variables if you want to tweak it&apos;s behaviour. &apos;cd&apos; into the variables store to see them
  48. For example, want to see the preferences you can change?
  49. It&apos;s worth acknowledging that “dir” doesn&apos;t make much sense in these contexts. But then, dir doesn&apos;t really exist. Remember what I said about PowerShell commands all being verb-noun ?
  50. So how does &apos;dir&apos; fit into all this?
  51. A quick check with &apos;Get-Command&apos; shows what &apos;dir&apos; is. It&apos;s an alias for &apos;Get-ChildItem&apos; – a command that gets the &apos;child&apos; items of a resource. Which makes more sense for getting a list of certificates in a certificate store, for example. There are several built-in aliases – some, like &apos;dir&apos;, are there to make PowerShell a bit familiar for those of us who are a bit set in our ways.
  52. Others are there to save us a bit of time. I mentioned before that PowerShell&apos;s verbose command-set is great for making instantly readable scripts. And this is true. Verbose is great when you&apos;ve got to look after someone else&apos;s scripts. Or scripts that you wrote months ago and have completely forgotten about. But it sucks when you&apos;re just hacking about at the command line. So you don&apos;t have to type in the full name for arguments – just enough to differentiate it. You don&apos;t even need to type the full name of commands – you can use an alias. Even with tab-completion to help, &apos;gps&apos; is still quicker to type than &apos;Get-Process&apos;.
  53. But how would you know that it&apos;s &apos;gps&apos;? Well, okay, so that is a bit fiddly. But, again, it is consistent, and therefore quite learnable. &apos;Get-Command *Alias&apos; reminds me that the command I need to get a list of aliases is &apos;Get-Alias&apos; (surprise!) Look at all of the aliases that start with &apos;g&apos;. They are all (pretty much) &apos;Get-&apos; commands. &apos;Get-&apos; commands are shortened to g-something-something. Look at the aliases that end in *al. They are the alias commands. So the alias for Get-Alias is gal.
  54. Now on to my favourite aspect of PowerShell. It&apos;s best explained with an example. How would you stop a particular process in UNIX-land? “ kill -9” followed by the process id. How do you get the process id? You can use &apos;ps&apos;. Easy!
  55. Except... it really isn&apos;t. I&apos;m not even sure that this line would work - I never really liked awk, sed, and all of those. The problem is that these pipes are piping text – &apos;ps&apos; identifies the process id, but some of that information is lost when it is printed out in a table. You then need to recreate that context by knowing which column the process ids will be in, and trying to grab that text out. We lose too much information by relying on passing text between commands. Consider commands that return a date – when piped to another command – which need you to recreate the date from the text representation of it. This is what makes this sort of thing so complicated. Converting stuff into text means we have to learn complex ways to get stuff out of text like awk.
  56. This is the PowerShell equivalent. Perhaps a contrived example, but it makes the point well.
  57. Why is it so much easier? Because PowerShell is an object-oriented shell. It doesn&apos;t pass strings between commands – it passes the whole object. (.NET objects, as you might have guessed, as something produced by Microsoft). So &apos;Get-Process&apos; gets the .NET object representing the notepad process(es), and passes it to the &apos;Stop-Process&apos; command.
  58. So let&apos;s go back to the first command that I started with – using Get-Process to get a list of the current running processes. People used to &apos;ps&apos; might have assumed that Get-Process prints a list of processes. It does appear to. But it doesn&apos;t! Get-Process returns a number of process objects. It just so happens that, if you don&apos;t tell what PowerShell what to do with an object returned to it, it will helpfully print out some of it&apos;s properties in a way that it thinks is the most appropriate (in this case, a table). But, you don&apos;t have to let it do that. You can tell PowerShell to send the output somewhere else, print them to the console in a different format, or... do something else with them.
  59. How do you know what you can do with an object? This brings us to the fourth of our &apos;HELP&apos; commands: Get-Member.
  60. If you pipe an object to &apos;Get-Member&apos;, it returns a list of properties that the object has, and methods it has that can be invoked.
  61. You don&apos;t need to accept the default output chosen by PowerShell, you can choose which properties you want it to display.
  62. Select It&apos;s quite SQL-like in it&apos;s syntax. You select the names of properties from the available properties in the &apos;Get-Member&apos; output.
  63. And again, to reiterate an earlier point, as with most things in PowerShell, wildcards are supported. If you are looking for process properties relating to “size” you could...
  64. 1) use Get-Member to get a list of all properties with &apos;size&apos; in the name, then use &apos;Select&apos; to get them or, more simply, 2) &apos;Select&apos; all properties from the Process objects which have &apos;size&apos; in the name. ( In hindsight, looking at this output, you&apos;d probably also want the process name in the output, but the table it draws makes the point how you can get the output you want ).
  65. Remember what I said about “all commands are verb-noun”? So what about &apos;Select&apos;? I keep contradicting myself but noone stops me :-) Again, it&apos;s an alias. &apos;Select&apos; is an alias for “Select-Object”.
  66. It&apos;s one of a number of utility commands. If you&apos;re used to object-oriented programming, you&apos;re familiar with the idea that everything can be described as an object. The noun part of a verb-noun command describes the object that the command can be used on. So these commands can be used on any object. For example, you can compare objects or group them by identified properties. To get a full list of these utility commands, we can use &apos;Get-Command&apos;
  67. These are the utility commands I tend to use the most often. Sort, Select, Where, Compare As with Select, although in full these commands would be written with “-Object”, they are typically written using the shorter alias
  68. So you can use &apos;Where&apos; to apply a filter to the set of objects returned by a command. Again, if you&apos;re used to SQL-type syntax, this sort of thing will look familiar.
  69. Here I want a list of processes which have a virtual memory size greater than 200 megabytes. ( Notice the use of -gt for greater-than – rather than the “&gt;” character, which can be confused with redirects in a command line ) You can make this filter as complex as you like – using -and and -or to set filters on multiple properties. ( Notice that this is put in curly brackets as it is something that needs to be executed – essentially it needs to be something that will return true or false )
  70. Piping the list of objects to Where-Object returns another (smaller) list of objects – a subset of the set of objects given to it. This subset can then be piped to Sort-Object. Here I am identifying the property to sort by - virtual memory size (using the short alias to save me some typing), and specifying the direction to sort in.
  71. Finally, I pass my sorted subset of the full list of process objects to Select-Object – specifying the properties that I want to be displayed. ( Note that these don&apos;t need to be properties that I&apos;ve used to filter or sort – as at every stage we have been passing the whole process object between the pipes, and no information has been lost ). Again, I&apos;m using curly brackets to show something that I want to be executed. Rather than displaying “virtual memory size” in bytes, I think it would be more helpful to see it displayed in MB. So I&apos;ve told Select-Object to return me the virtual memory size divided by 1024.
  72. Another (albeit bizarre) example of wildcards in action. Get me a list of all processes which start with an a, b, or c, and end with a letter c through q.
  73. Format the list grouped by the &apos;Company&apos; property
  74. We&apos;ve looked at the utility commands – commands which can be used with any object. And it&apos;s worth learning these – you learn them once and can use them with any command for any product that you need to administer with PowerShell. In a similar way, it&apos;s worth getting familiar with the common parameters that all* cmdlets support. * - well... ish.
  75. To find out more about these, you can read the help topic about it Get-Help about_commonparameters will return all of the information about them, and how they work.
  76. In short, there are four parameters that it&apos;s useful to learn.
  77. These are best explained with an example. Consider our Get-Process piped to Stop-Process example again.
  78. -WhatIf useful if you&apos;re not sure that you&apos;ve got a command right before you run it the -WhatIf parameter tells a cmdlet to not actually do anything, but to tell you what it would have done if you had run it so for my “Stop-Process -WhatIf” example, you get a list of processes that would have been stopped
  79. -Confirm useful if you think you&apos;ve probably got a command nearly right, but want to double-check something before it&apos;s done the -Confirm parameter tells a cmdlet to ask for confirmation before doing anything so for my “Stop-Process -Confirm” example, you get an “Are you sure?” prompt before each process is stopped
  80. I said before that when you have a list of objects returned by a command, you can tell PowerShell to send them somewhere else.
  81. For example, you can send it to a CSV file (comma-separated-values)
  82. This means that you can look at the objects in Microsoft Excel. (From where you can draw graphs or charts, or perform the sort of neat statistical analysis that I never really understand).
  83. CSV files are also a nice way to store a collection of objects so that you can use them later. Recall that I mentioned one of the utility commands earlier: “Compare-Object” Compare-Object – give this cmdlet two sets of things, and it will compare them (or just the properties that you specify), working out which are different
  84. So you can do this Compare two lists of processes The first – the list of process objects you get when you import the CSV file containing the process objects we exported earlier The second – using Get-Process to get a current list of processes We can compare the system now with the processes that were running at an earlier known state.
  85. And you can see that there are some differences Snitter and Twitteroo ( don&apos;t ask ) are running now but weren&apos;t before And a wiki app, calculator, notepad, SplashID and TaskToday were running earlier but aren&apos;t now This is a very powerful capability for something that only needed a couple of short commands.
  86. I mentioned that Compare-Object can compare specified properties of objects.
  87. So what if we did the same as before, but getting Compare-Object to compare both the name and the workingset of the process objects. This lets you see not only whether there are any processes which weren&apos;t running before, but if any of the processes have a different working set size to what they had before. You could take this further by specifying how much of a change – for example, looking for processes which have had a substantial change in the amount of memory since a previous “known good” state.
  88. That covers PowerShell&apos;s built-in commands. But you&apos;re not limited to that. As PowerShell is built on top of .NET, you can use any .NET library at the command line, too. In short, pretty much anything that can be done in a .NET application can be done in a PowerShell script.
  89. Let&apos;s take a look at the sorts of .NET objects you can use.
  90. If I do a quick sum at the command line, you can see that I get back the result &apos;5&apos;. But what type of object am I getting back?
  91. An &apos;int&apos; If you&apos;ve done any C# coding before, you will probably be familiar with the GetType method.
  92. But you can also run the same PowerShell commands that we&apos;ve gone through – like using Get-Member to see what methods you can invoke on the object
  93. Having the whole .NET library means that you have some very powerful string handling methods available for use in your scripts.
  94. If I use Get-Member on my string object, you can see how many there are – this is just the top of the list before it scrolled off the page. Searching, editing, cutting out substrings, modifying... there is a lot that you can do. And if you&apos;ve been a .NET programmer, then you already know how to do it. ( If you&apos;ve not been a .NET programmer, then PowerShell is a nice way to learn the .NET basics )
  95. Another object type that is useful in sysadmin scripts is the DateTime object
  96. There is actually a built-in PowerShell cmdlet to create a datetime object or get the current date: Get-Date But here I want to ignore that for the moment to show how I can directly access .NET namespaces The syntax is a little quirky – you wrap the namespace in square brackets, then use a double-colon to access something. But you do get used to it. And you can see here where I&apos;ve piped this to &apos;Get-Member&apos; that the range of date methods and properties is huge – there is a lot that you can do with a datetime object.
  97. Another neat example of using .NET function directly at the command line
  98. Here I am downloading the RSS feed for the BBC News website I then pipe that XML object to Select-Object, and choose the title, description and date properties for display Note: - square brackets to cast an object to a type – where I cast my object to be an &apos;xml&apos; object - dollar sign for variables - I assigned my $bbc_news_rss_url variable on the previous line to keep this line a little shorter - wildcards again – saves me having to spell “Description”, or remember that the date field in XML is called pubDate - Select has additional parameters -first and -last which let you see, in this case, just the first eight objects.
  99. Quickly... let&apos;s take the anything-in-.NET example to a ridiculous extreme
  100. Here I want to use a library that is not part of the core .NET That&apos;s fine – you can load any .NET DLL into PowerShell with a single command. You can see here that I&apos;ve loaded Windows Forms into PowerShell. I can then create a Form object, set a few properties, and, when I enter showDialog() ...
  101. ... my Window appears. This is just .NET programming done interactively. Anything that you can do in a .NET program can be done in a PowerShell script. And any function available in a .NET DLL can be loaded in, and made available to PowerShell scripts.
  102. This should give you a clue as to the answer to the last question I wanted to tackle – how can you extend PowerShell so that it can be used to administer your product. But first... I think it&apos;s worth addressing:
  103. Why? Why might you want to do this? Let me explain with an example. I used to work on a product called WebSphere MQ. I have been working to add support for WMQ administration to PowerShell, so I&apos;ll quickly explain why I thought this would be useful
  104. It&apos;s not really important to understand what WMQ is for the purposes of this, but for those wanting a little background, WMQ let&apos;s you have a conceptual server called a “Queue Manager” which hosts a number of “queues”. You can then put and get messages to these queues. So imagine a sys admin. He uses PowerShell for his work – to administer a number of Microsoft server applications, and to do basic user and system admin stuff. He&apos;s now been asked to be responsible for WebSphere MQ admin, which he&apos;s never done before.
  105. This means probably having to learn how to use &apos;runmqsc&apos; – the command line tool that comes with WMQ. Okay, so this isn&apos;t the end of the world, but it is a different command – with it&apos;s own quirky syntax, it&apos;s own approaches to parameters, it&apos;s own nuances. It&apos;s fine when you get used to it, but it&apos;s not immediately intuitive. You can see here that to get a list of the queues on my queue manager server, I&apos;ve done DIS (for Display) QL(for a local queue) (*) (to get all queues – you wrap the name in parentheses) Fine when you know how, but it probably wouldn&apos;t have been our sys admin&apos;s first guess
  106. Remember that our sys admin knows that in PowerShell, commands will be a verb followed by a noun. In fact...
  107. The convention for commands administering external products or systems is that the noun is broken up into the product name followed by the object type.
  108. Knowing that the command will include the product name means our sys admin can use Get-Command to try searching for it...
  109. “ Get-Command *WMQ*” returns a list of commands. Many of them will look familiar to our sys-admin For example, Get-WMQQueue will probably return a list of WebSphere MQ queue objects
  110. So our sys admin gets asked his first question... Okay, so first, he&apos;d probably need to get some clarification
  111. which queues are used by the sales team? brilliant – they&apos;re all named SALES dot something easy enough
  112. what is “a bit full”? they mean queues that are 10 or fewer messages away from their maximum depth this could be expressed in a few ways (depth + 10 &gt; max depth etc.) but for now, let&apos;s go with this way
  113. how much should the max depth be increased by? easy enough – just double whatever it is at the moment ( probably a bit extreme, but it will do for our example! )
  114. This is what our sys-admin might try
  115. To start off with... let&apos;s double-check we know what command we want. To be honest, tab-completion would have been enough to find this. To get a list of queues, we know we want a Get- command, and we know that it will have “Queue” as the object type
  116. So we know that Get-WMQQueue will return us a list of queue objects Now, we don&apos;t want to mess around with all queues – just the SALES team&apos;s queues which are getting full. But our sys admin doesn&apos;t need to learn any quirky parameters for this new WMQ command – he can use the common utility commands that work on any object. To start with...
  117. Where Where the name is like SALES dot something And the current depth is bigger than the max depth minus 10 Other than needing to know the property names, there is nothing new in here. And our sys admin knows that he can use Get-Member to get a list of properties if he needs to check All of this is something that a PowerShell admin could have done in response to the query we saw before, even without knowing anything about WMQ
  118. Just to check, we can run the command like that – getting us a list of objects I&apos;ve added a Select Name, CurrentDepth, MaximumDepth to get us the interesting bits...
  119. Sure enough, there are some queues which are getting a bit full SALES.2 is five away from being full SALES.3 is six messages away and so on
  120. Now let&apos;s do the same command again, but this time make the changes. Just as the verb to get an object is always “Get”, the verb to modify an object is always “Set”.
  121. If we were going to adjust the maximum depth to the same value for each of the queues returned by the previous command, then I could have just piped it to Set-WMQQueue For example, this command will set the description property of every queue to “hacked!” Get-WMQQueue returns me a list of queue objects Set-WMQQueue will modify the description property of every object it is given
  122. But in this case, to double the existing maximum depth property for each queue, our sys admin will need to be a little more clever This can be done with another of the utility commands: ForEach $_ represents the current object So this line runs Set-WMQQueue on the current queue object given to it, setting the MaximumDepth property to the current queue object&apos;s MaximumDepth times 2 Tthere is nothing WMQ-specific here. And nothing that a PowerShell admin wouldn&apos;t have been able to do – without needing to be an WMQ expert. This would be possible because they are mainly using the standard PowerShell commands (and the new WMQ ones have been named and work in a way that is consistent with the PowerShell norms).
  123. And there we go. A quick Get-WMQQueue command to confirm that the depths have been adjusted as you&apos;d expect. Not only has this been much quicker than it would have been possible to do with the existing runmqsc command line tool, but – perhaps just as importantly – the learning curve has been massively reduced.
  124. I mentioned that our sys-admin might not know the properties that a WMQ queue object has.
  125. It&apos;s easy to check – pipe the output of the Get-WMQQueue command to &apos;Get-Member&apos; and you get the full list
  126. You can see the type of every property You can even see which ones you&apos;re allowed to modify. For example - I cannot set the CurrentDepth – this is a property determined by the number of messages on the queue, and isn&apos;t something our sysadmin can modify. If he tries, PowerShell will return an error that it is not possible, but even here, it is providing doc and guidance in the standard way
  127. The fact that properties still have their type – they are not returned as text that needs to be parsed or interpreted – means that you can use them in queries
  128. For example, if I want a list of queues that were created between the 15 th October and the 20 th October... Pipe the objects returned by Get-WMQQueue through Where, with a query that uses date objects to compare against Again – none of this is WMQ-specific, other than the name of the CreationDateTime property which you can get from Get-Member
  129. Our sys-admin&apos;s next job
  130. Easy Get all the queues, use a Where to filter it to the ones which start with the right letter, and have something in their cluster name property Then pipe that set of objects to a Set-WMQQueue command Remember that aliases are not limited to commands – parameters can have aliases defined, too. To make life easier for people who are used to the existing runmqsc command line tool, you can have property name aliases that look like the ones they might be used to. So instead of MaximumDepth, an experienced sysadmin could use:
  131. MAXDEPTH Doesn&apos;t matter – will do the same thing
  132. One last quick example The point of this one is to highlight that objects in .NET typically have properties which are objects themselves Here we will be getting a channel. What a channel is is not important, but what is important is that one of the properties of a channel object is a handle to a queue manager object. We want the name property of that queue manager
  133. The syntax is a bit icky, but it&apos;s still essentially the same idea It all goes in curly brackets because it needs executing You use $_ to get the current channel object $_.QueueManager to get the queue manager handle $_.QueueManager.Name to get it&apos;s name
  134. Finally, remember that our new WMQ sys admin can output queries to CSV spreadsheets or HTML tables. Remember how we used Export-CSV to export the current process information to a spreadsheet? This let us do comparisons with a known state – seeing what processes have changed and so on. The sys admin could use the same techniques that he is used to with WMQ. Export the queue objects to CSV then schedule regular Import/Compare commands to see if any of the queue properties are significantly different from the known good state. Again, not only is this sort of monitoring ability easy to do, but it&apos;s consistent and with a much reduced learning curve.
  135. That&apos;s the sales pitch out of the way. This is why I think adding support for PowerShell admin to a product has value – you get access to a powerful shell and scripting environment, and for users familiar with PowerShell, learning your product becomes much easier. Assuming that you are convinced that you should do this... how do you do it?
  136. I&apos;m going to stick with WebSphere MQ as an example. WMQ has a .NET library. And remember – anything that you can get at in a .NET DLL can be loaded into PowerShell. So all of the stuff in manuals and books like these can be used.
  137. I said before that PowerShell is a broad environment – covering anything from formal polished GUIs to an interactive shell where you can hack about and try things out. Adding PowerShell function runs the range from writing ad-hoc scripts to formal production function, and pretty much anything in-between What do I mean by that?
  138. You can write informal scripts These are the things that a sys admin will throw together for his own use, to save time by not repeatedly entering common commands. They aren&apos;t formal. You don&apos;t have to bother naming arguments, or specifying their type.
  139. At the other end of the spectrum, you can write production scripts with typed, named arguments. Function with rich error handling, support for multiple output streams (for example, sending errors to one destination, debug output to another, standard output to another etc.), and so on.
  140. This is often an evolutionary process. You start by running things at the shell, and getting into habits of commands you frequently run which you can string together in a function. Over time, these might be built up into a script. Later, as you find more uses for them, you might generalize them – parameterizing them and so on Eventually, you could clean these up and productize them to the point where they can be shared with customers or third-parties.
  141. Let&apos;s start by looking at an ad-hoc approach to adding WMQ support to PowerShell. The code isn&apos;t very important, and I wont read through it all, but there are a few points worth highlighting. 1) We put all of this in a .ps1 file. If you put this in the right directory, it will be available to every new PowerShell window you open 2) You wrap your script in a &apos;function&apos; block
  142. I&apos;ve skipped a couple of steps and got a bit advanced by using Trap (sort of like a .NET try...catch) to capture errors If an exception of the type MQException is thrown, this bit of script here gets run
  143. If you want to display a message, you don&apos;t print to the console, you use Write-Host Because the user might not want the output going to the console – they might be directing it to another command. So Write-Host returns the text to the appropriate “host”
  144. You use Write-Output to return stuff Remember that commands are designed for living in a pipeline – you don&apos;t return a finished set of objects. You return each object as you get it.
  145. I wont read through the details of these, but the slides are available if you want to examine them later. I&apos;ve included them to show some examples of syntax Remember: - square brackets to cast - namespaces in square brackets with double-colon to access things - New-Object (one of the utility cmdlets) lets you create anything available to you in .NET
  146. Remember – if you are converting C# code to a PowerShell function, you need to change your comparison operators. PowerShell uses operators like -gt -ge -lt -le -eq -ne
  147. And here we go – the function on the previous half-dozen slides lets you do this. And most of it came from .NET code that I had lying around anyway – converting it to a PowerShell script took no time at all. http://dalelane.co.uk/blog/?p=153 – some more info on this that I wrote a while ago
  148. Let&apos;s look at the other end of the spectrum – you can produce a DLL “snap-in” with new cmdlets to extend the core PowerShell set. The easiest tool to do this with is probably Visual Studio. And the plugin at this URL makes it even easier. It lets you create Visual Studio projects that already have the settings configured to build DLLs suitable for PowerShell snap-ins. And it adds menu items to create new CmdLet objects – these create new skeleton classes with the mandatory methods already in place, ready for you to fill in an implementation. This all gets you a development environment ready for writing your first Cmdlet without needing to worry about how to build it. ( There is a nice blog post linked off that page which gives more detailed instructions, too. )
  149. Writing a Cmdlet is a bit tricky, and I don&apos;t have time to go into much detail. In the next few slides, I will give a quick introduction, but I would recommend this MSDN page as a place to start if you decide to give this a try – it&apos;s a walkthrough taking you step-by-step through the work involved in writing a Cmdlet.
  150. I&apos;d also recommend the Cmdlet guidelines here. These are a good place to start when planning what your Cmdlet should do. This is the definitive place for finding out what norms your Cmdlet should conform to.
  151. The walkthrough takes you through the steps necessary to write an implementation of Get-Process (With the extension installed) Visual Studio will create you the skeleton Cmdlet class – with ProcessRecord being the method you need to implement. So for your product, you would replace this code in ProcessRecord with code which got a particular type of object used in your product. For WMQ, this could be queues, for example.
  152. Visual Studio will compile your code into a DLL.
  153. You then install this using InstallUtil
  154. Then, open a PowerShell prompt and run Add-PSSnapIn to add the new cmdlet(s) to your PowerShell environment
  155. I mentioned before that the PowerShell functions can be polished into production-quality commands that you can share with customers or third-parties. If you write your own Cmdlets you could share this as a DLL, suitable for adding to PowerShell as I&apos;ve just shown.
  156. Or, you could build them into a shell suitable for sharing
  157. Make-Shell lets you create custom shells suitable for sharing – so you can provide your customers or third-party with a finished executable that includes your new cmdlets.
  158. I&apos;ve talked about how to add new function to PowerShell – by writing scripts or custom cmdlets This isn&apos;t the only way you can extend PowerShell.
  159. Remember the different data sources that PowerShell supports. You might not want to extend the functions that PowerShell has, but to add support for a different data source. This is also possible, by writing a custom provider. There wasn&apos;t time in an (already packed!) hour presentation to talk about this, but if there is enough demand, I could go through this in a separate presentation.
  160. So – to recap. Windows PowerShell – an environment for system administrators, providing support for advanced scripting and an interactive shell, as well as a platform on which to build GUIs. An object-oriented shell which conforms to standard naming and function patterns, letting you move from product to product with a reduced learning curve. A .NET shell, giving access to anything in the .NET landscape from the command line. Finally, an extensible environment, with support for scripts, as well as custom functions (through cmdlets) and data types (through providers).
  161. Please feel free to contact me if you have any questions. ( For IBM audiences ) I&apos;m happy to help with any PowerShell projects – if you&apos;re looking to add PowerShell support to your product, please don&apos;t hesitate to get in touch.