Sunday, August 30, 2015

PowerShell - The Call Operator "&"

The call operator "&" is a powerful feature in PowerShell. If you place this operator in front of a string, or a string variable, the string will be interpreted as a command and executed just as if you had input it directly into the console. Let put a command (Dir) in a variable and if you output the contents of the variable, only string will be output:

$myCommand = "Dir"
$
myCommand
Dir

If you type the call operator "&" in front of it, the command will be executed:
& $myCommand

The call operator will not run an entire instruction line but only single command. If you
had also specified arguments for the command, you will get an error:
$myCommand = "Dir C:\"
& $
myCommand

Event if you put an space in command name, you will get same error. For example:
$myCommand = "Dir "
& $
myCommand
 Also generates the error.

Another way to assign a command to a variable is using Get-Command cmdlet, and then use the same call operator to invoke this command.
$myCommand = Get-Command Dir
& $
myCommand

But keep in mind that & $myCommand calls the actual command in $myCommand. You may specify any arguments after it, but you can't put the arguments directly in $command because the call operator always executes only one single command without arguments. So following call will work:
$myCommand = "Dir"
& $
myCommand "c:\"

PowerShell - Workflow

Workflow functionality with PowerShell gives you the benefits of automation capabilities.  For example, you need to perform a long-running task that combines multiple steps in a sequence, wrokflows will do the job.

For creating and calling, it is same like a function, lets define our first workflow
workflow Workflow1 {
"My workflow is started"
"Task1 is completed"
"Task2 will take some time - 5 seconds"
Start-Sleep -Seconds 5
"Task3 completed"
"Workflow completed"
}

We can run the workflow just like any other PowerShell function. It looks and acts just like a normal function. Simply call workflow as:
Workflow1

Output of our workflow is:
My workflow is started
Task1 is completed
Task2 will take some time - 5 seconds
Task3 completed
Workflow completed

We can use the PowerShell Get-Command to get details about the workflow we created.
Get-Command Workflow1

Adding -syntax parameter, will display the syntax tempalte for calling workflow.
Workflow1 [<WorkflowCommonParameters>] [<CommonParameters>]

If you have a large no of activities within a workflow, and at some point we want to save a particular state of the workflow. For this we need to simply call this cmdlet within the workflow:
Checkpoint-Workflow

Workflow is an extensive topic in PowerShell. Here I created a simplest workflow just for starting purpose. Hopefully will try to post more on this topic as I get time. If you want to read more on this topic please tell me by your valuable comments, that will help for future posts.

PowerShell - Create / Import / Remove Module

You can write PowerShell script and save in separate file for reuse in different situations. Lets first create the module.

Create a file with extension .psm1, and place a sample function like this:

function Get-TestMessage()
{
    Write-Host("Get-TestMessage function is involed")
}

Now we have a TestModule.psm1 file with one function Get-TestMessage(). Place this module either in one of the PowerShell default module folders that you can query by this special variable $env:PSModulePath. Or also you can place anywhere on your disk, but in this case you have to define the complete file path for the module while importing.

Now, lets create another module, lets say WorkingModule.psm1. Here we want to use a function from the TestModule. We have to import TestModule by this cmdlet:
Import-Module "C:\PATH_TO_YOUR_MODULES_FOLDER\TestModulePSM.psm1"

And now we can simply call our function and it works.
Get-TestMessage

You can find the available functions defined within a module by passing the module name in -module parameter for Get-Command cmdlet.
Get-Command -Module TestModule

In our case it will only return one function.

Once you finished work with a module, you can remove that module by simply call this cmdlet.
Remove-Module TestModulePSM

If this article helps you then please post your valuable comments.

Saturday, August 29, 2015

PowerShell - Strings

We can define a literal string surrounded with single quotes and that does not interpret variable expansion or escape characters.
$myString = 'Hello World'

Also we have strings with double quotes called as expanding strings, here PowerShelll expands variable names (such as $myVar) and escape sequences (such as `n) with their values.
$myString = "Hello World"

We have to place two of that string’s quote characters together to add the quote character itself

$myString = "This string includes ""double quotes"" because it combined quote characters."
$myString = 'This string includes ''single quotes'' because it combined quote characters.'

Lets create a variable that holds text with newlines or other explicit formatting.
$myString = @"
This is the first line.
            Now expand it to second line.
    Still continues with string text including new lines and tabs.
"@
$myString


PowerShell uses a backtick (`) character as escape sequences. In this example `n will start a new line.
$myString = "My heading text`n----------------"

Strings dynamically accepts another variable's value.
$myVar = "PowerShell"
$myString = "We are working with $myVar"
$myString
We are working with PowerShell


If you want to prevent PowerShell from interpreting special characters or variable names inside a string. A nonexpanding string uses the single quote character around its text. Now it will not place the variable's content but place the same as we typed.
$myVar = "PowerShell"
$myString = 'I have just defined a variable named $myVar'
$myString

 
You can repeat a string multiple times. Lets say, we want to append "0" to some other value. So for this just put the character inside quotes and multiply it with the number of times you want to repeat. For example, here I want to append ten 0s on the left side with my value "1".
$('0' * 10) + "1"
00000000001


Like we have string.Format() method in C#, we can format our strings in the same way also. We have to use -f after at the end of string quotes, then put the variables we want to set in placeholders. For example:
$var1= "Strings"
$var2= "PowerShell"
$myString = "We are working with {0} in {1}" -f $var1,$var2
$myString


Note that, same like C#, first variable in the sequence will be placed in the first placeholder, second variable in second index and so on.

PowerShell - Event Log

You can use the Get-Eventlog cmdlet to access log entries. You can use this cmdlet for two purposes, one is to list the event logs, second you can use it to extract all the events within a specific event log.

-List paramter is used with this cmdlet to list down only event logs.
Get-EventLog -List

If you wanted to get a display of all the entries in the System log, you can just put the log name ('System' in this case) with cmdlet:
Get-EventLog System

But depending on the number of records in the event log, you might get a long scrolling in shell. So its better to use the PowerShell filters. Use Where-Object to pass the information retrieved by Get-Eventlog through the pipeline while allowing only those entries through that meet your criteria. For example the following command will list down all the event in the system events log, that are recorded today.
Get-Eventlog System | Where-Object {($_.TimeWritten).Date -eq (Get-Date).Date}

We also have the -newest parameter. You can simply get only the last x number of events recorded in the log. For example, this command retrieves the last three events written to the System event log:
Get-EventLog System -newest 3

Or you can put the -Format-List parameter for better view:
Get-EventLog System -newest 3 | Format-List

You can use the methods of the .NET framework, to make event entries:
[Diagnostics.EventLog]::WriteEntry("Application","My test event","Information")

To see if this event is successfully recorded, you can check the Event Viewer:
eventvwr.msc

Or you can use the same -newset parameter with cmdlet to view this test event.
Get-EventLog Application -newest 3 | Format-List

PowerShell - Services

PowerShell provides good support for managing windows services. You can list down, start, stop the services from shell. Lets start:

This command will give you the avialable cmdlets for managing services:
Get-Command *service* | Where-Object {$_.CommandType -eq 'cmdlet'}

Get-Service                                                                          
New-Service                                                                          
Restart-Service                                                                      
Resume-Service                                                                       
Set-Service                                                                          
Start-Service                                                                        
Stop-Service                                                                         
Suspend-Service                                                                      

List all services beginning with "sql":
Get-service sql*

This command will give you only running services beginning with "sql":
Get-Service sql* | Where-Object { $_.status -eq 'Running' }

Lets try to start 'SQL Server Browser' service
Get-Service | Where-Object { $_.DisplayName -eq 'SQL Server Browser' } | Start-Service

You need administrator rights to run this command.

In-case you get this error:
SQL Server Browser (SQLBrowser)' cannot be started  due to the following error: Cannot start service SQLBrowser on computer '.'.
Please refer to this post:
http://idreesdotnet.blogspot.com/2015/08/powershell-start-service-service-x.html


All these cmdlets needs you to have administrator rights.
  • New-Service                                                                          
  • Restart-Service                                                                      
  • Resume-Service                                                                       
  • Set-Service                                                                          
  • Start-Service                                                                        
  • Stop-Service                                                                         
  • Suspend-Service                                                                      

PowerShell - Start-Service : Service 'x' cannot be started due to the following error: Cannot open x service on computer '.'

If you want to start a service through PowerShell you might get this error:

Start-Service YOUR_SERVICE_NAME

Start-Service : Service 'x' cannot be started due to the following error: Cannot open
x service on computer '.'.
At line:1 char:72
+ ... here-Object {$_.DisplayName -eq "x"} | Start-Service
+                                                             ~~~~~~~~~~~~~
    + CategoryInfo          : OpenError: (System.ServiceProcess.ServiceController:ServiceController) [Start-Service],
   ServiceCommandException
    + FullyQualifiedErrorId : CouldNotStartService,Microsoft.PowerShell.Commands.StartServiceCommand

We get this error because we are not running the PowerShell with Administrative privileges. Just right click on PowerShell and then click 'Run as administrator'. You will get your cmdlet worked.

Similarly you might have to do the same thing for following service commands:
  • New-Service   
  • Restart-Service
  • Resume-Service
  • Set-Service   
  • Start-Service 
  • Stop-Service  
  • Suspend-Service