Look at PowerShell

Windows PowerShell is a command-line shell designed for Windows, targeting system administrators. This shell is similar to that of CSH, BASH on Unix/Linux OS. It is built on using .NET Framework. This shell consists of a console for interactive prompting and a scripting environment to automate the tasks. This shell can accept/return .NET objects. PowerShell uses the concept of command-lets (cmdlets) to interact with it. Command-lets are the basic building blocks that can perform an atomic (single-function) task. We can redirect output of one cmdlet as input to another cmdlet for implementing complex functions. PowerShell consists of more than 100 cmdlets and allows us to create our own cmdlets and share it across. By using PowerShell, we can access our file system, registry etc.

Unlike other shells like CSH, PowerShell won't process text entered. Instead, it processes .NET objects. PowerShell comes with a handy set of built-in commands to perform basic tasks. All shell commands uses same parser. We can even develop our own cmdlets. First, we will look into built-in cmdlets. A cmdlet is a command that manipulates objects of PowerShell. Most of the cmdlets are easy to understand by their names. Generally, a cmdlet name will have a verb like get or set followed by a noun like "service" or "format" having "-" in between. For example, get-service will list all the services of our machine. PowerShell is having its own language for implementation, instead of using existing language. We can download PowerShell 2.0 from here. It is available by default in Windows Server 2008.

PowerShell internally interacts with .NET objects for its working. For example, when we get all processes of our machine using "get-process" command, it internally gets an object representing .NET Process class. When we view the properties of a process, we are internally getting those using process object's properties. We can get the complete information on a command by using get-help <command-name> -detailed command.

Get Started with Windows PowerShell

Let's start with a simple example, go to your Start menu >> Windows PowerShell 1.0 >> Windows PowerShell.

We will type "get-process" to get list of all processes running on our machine. It will list all processes and its properties like process id, process name etc. Now, type "get-process | get-member" command, this will list typename of the .NET object and a list of properties and methods of Process class. In above command, we are redirecting the output of "get-service" as input to "get-member" using pipeline operator (|). By using pipeline operator, we can even redirect the output to a printer or a file. We can use man (UNIX style) command to get help on a particular command. Internally, get-help or man command calls single function to perform the task. This is achieved using aliases of a command. We can list all the cmdlets available using "get-command". Cmdlets can accept parameters identified by a hyphen (-) preceding the parameter name. We no need to type complete parameter name, but you only need to enter enough characters to distinguish it from other parameter names. For example, "get-process" command has a parameter "name", but we can just type "get-process -na winword" to distinguish from other parameter names.

We can format the output of a command using format cmdlets. Following cmdlets are used to format the output:

  • Format-List
  • Format-Custom
  • Format-Table
  • Format-Wide

For example, when we type "get-process | format-list", it will list the output in a clean format in List format. Few cmdlets might be having lengthy names to type, in order to save time we can define aliases for it. We can get list of all aliases using "get-alias" command. We can get a aliases for a particular command using below syntax:

"get-alias | where-object {$_.definition -eq "<cmdlet-name>"}".

Example:

get-alias | where-object {$_.definition -eq "get-process"}

We can create an alias for a command by using below syntax:

  "set-alias <alias-name> <command-name>".

Example:

set-alias testalias get-process

We can delete an existing alias using:

"remove-item alias:<alias-name>".

Example:

remove-item alias:testalias

We can get the contents of a environment variable using "$env:<variable-name>" command. We can even update an environment variable using

"$env:<variable-name += ";new-value">".

Example:

$env:temp +=";c:\temp"

We can move into windows registry using "cd hklm:" command. Similarly, we can move into certificates using "cd cert:" command.

we will look into scripting capabilities of it. Normally, we use to write a set of commands (cmdlets) to perform a complex task. Sometimes, we might need to do that complex task repeatedly. Instead of typing those commands everytime, we can save them to a file called as script file. We can run the script file, when ever we want to perform that task. The extension for PowerShell script file is ".ps1". We can run a script by using command prompt.

PowerShell scripting language is having rich set of constructs to create simple to complex scripts. It supports looping, branching and variable assignment etc. PowerShell is having its own scripting language, instead of reusing existing languages.

In order to avoid spreading of malicious code in the form PowerShell scripts, it uses execution policy. This execution policy allows us to determine whether scripts can run and they should include digital signature or not etc. In view of security issues, none of the PowerShell scripts run on double-clicking on its script file. We can scripts to automate the tasks that we use to do frequently. Let's look into the syntax and constructs available in this scripting language.

Arithmetic Operators:

+ addition, concatenation
- subtraction
* multiplication, string repetition
/ division
% modulus

Assignment Operators

= Assigns a value to a variable
+= Adds a value to a variable
-= Subtracts a value from a variable
*= Multiplies a variable by a value
/= Divides a variable by a value
%= Performs a modulus on a variable

Functions

function [MyFunction]
{
write-object $args[0]
}

Comparison Operators

-eq Equal
-ne Not equal
-gt -ge Greater than, greater than or equal to
-lt -le Less than, less than or equal to

Logical Operators

! and -not Not a single value
-and And two values
-or Or two values

Comments

# This is a comment.
for
for ($i = 0; $i -lt 5; $i++) {write-object $i}
if/elseif/else
if (condition) {...}
elseif (condition) {...}
else {...}
We can get a complete list of constructs from here.
Let's see how to write a sample script file. This script file will open an IE and logins into a site. Open your notepad and type below code in it:
function main
{
write-host "Opening IE 'n"
$browser = new-object -com "InternetExplorer.Application"
$browser.visible = $true
write-host "Opening c-sharpcorner.com"
$browser.navigate("https://www.c-sharpcorner.com")
[System.Threading.Thread]::sleep(15000)
write-host "Logging"
$document = $browser.document
$uname = $document.getElementByID("UID")
$uname.value = "aaa"
$passwd = $document.getElementByID("PWD")
$passwd.value = "aaa"
$loginButton = $document.getElementByID("btnSignIN")
$loginButton.click()
}
main

When we run this script file in PowerShell console, it will open the site and logs into it. This is an example of Web automation using scripts. In the same way, we can automate many tasks.

If you get an error message shown below, on running any script files. Than, we need to issue this command "Set-ExecutionPolicy Unrestricted" to run scripts.

we will look into creation of cmdlet using VS 2008. Since, there are no built-in templates for creating cmdlets in Visual Studio. We need to get templates provided here. After downloading the zip, install Windows PowerShell (CS).vsi for creating PowerShell templates.

Now, Open our VS 2008 and create a new project with name as SampleCmdlet as shown below:

 We will make our cmdlet to display the environment variables of our machine. Add a new item of type "Windows PowerShell PSCmdlet" with name as SampleCmdlet as shown below: 

Now, go to SampleCmdlet class and add below code:

[Cmdlet(VerbsCommon.Get, "SampleCmdlet", SupportsShouldProcess = true)]

    public class SampleCmdlet : PSCmdlet

    {

        #region Parameters

        [Parameter(Position = 0,

            Mandatory = false,

            ValueFromPipelineByPropertyName = true,

            HelpMessage = "Help Text")]

        [ValidateNotNullOrEmpty]

        public string VariableTarget

        {

            get;

            set;

        }

        #endregion

        protected override void ProcessRecord()

        {

            try

            {

 IEnumerator objEnum = GetVariables(VariableTarget).GetEnumerator();

             while (objEnum.MoveNext())

                {

  DictionaryEntry entry = (DictionaryEntry)objEnum.Current;

WriteObject("Key : "+entry.Key + " " +"Value : "+ entry.Value);

                }

            }

            catch (Exception)

          {

            }

        }

        private IDictionary GetVariables(string target)

        {

            if (target.ToLower() == "user")

            {

               return Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User);

            }

            else if (target.ToLower() == "machine")

            {

                return Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine);

            }

            else if (target.ToLower() == "process")

            {

              return Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process);

            }

            else if (target.ToLower() == "all")

            {

                return Environment.GetEnvironmentVariables();

            }

            else

      {

                return Environment.GetEnvironmentVariables();

            }

        }

    }

Here, we are passing a parameter named as VariableTarget to specify the type of environment variables need to be displayed. In ProcessRecord() method, we are getting key and value of the variable and sending it for display using WriteObject() method.

Now, build the solution. Here, we are getting environment variables based on machine, user or process. We need to register the dll using installutil tool. Go to VS/ PowerShell command prompt and run the below command:

InstallUtil <DLLName>. Now, add our SampleCmdlet to PowerShell commands using below command:

"add-pssnapin samplecmdlet". Finally, we can run the command (samplecmdlet "all") to get list of environment variables. In this way, we can write our own cmdlets using VS 2008.