Category Archives: Powershell

Powershell module to MapNetworkDrive

At my work, every few days I have to change the user and connect to a network drive. The mapping process every time used to be little bit difficult. I have created some powershell modules which helped me in this process. This is for my reference and if it helps others that’s great:
I have powershell 2.0 so the modules need to be created in VS 2008 for binary type modules, one can create powershell scripts and imports them as modules too. I wrote it in VS 2008, you need to add reference to System.Management and System.Management.Automation.dll(this is in powershell folder).

I wrote 4 different commandlets in this module, each will perform a different functionality.
Get-Drives – Gets all the logical drives and network paths
Get-FreeDriveLetter – Gets the available drive letter in the descending order which can be used.
Map-AuthNetworkDrive – Maps the network drive with the provided credentials or default credentials
Map-DisconnectNetworkDrive – Removes the map

Get-Drives

    [Cmdlet(VerbsCommon.Get, "Drives")]
    public class GetDrives: PSCmdlet
    {
        protected override void ProcessRecord()
        {
            try
            {
                var drives = CommonMethods.GetDrives();

                this.WriteObject(drives, true);
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001", ErrorCategory.NotImplemented, null));
            }

        }
               
    }

    //CommonMethods.GetDrives
 internal static IEnumerable<object> GetDrives2()
        {
            IList<object> driveInfo = new List<object>();
            try
            {
                SelectQuery query = new SelectQuery("Select DeviceID, DriveType, ProviderName From Win32_LogicalDisk");
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
                foreach(ManagementObject disk in searcher.Get())
                {
                    driveInfo.Add(new { DeviceID = disk["DeviceID"], DriveType = (DiskType)disk["DriveType"], ProviderName = disk["ProviderName"] });
                }
            }
            catch (Exception ex)
            {
                throw ex;

            }

            return driveInfo;
        }

  public enum DiskType : uint
    {
        Unknown = 0,
        RemovableDisk = 2,
        LocalDisk = 3,
        NetworkDrive = 4,
        CompactDisk = 5,
        RAMDisk = 6
    }

Get-FreeDriveLetter

   [Cmdlet(VerbsCommon.Get, "FreeDriveLetter")]
    public class GetFreeDriveLetter : PSCmdlet
    {
        protected override void ProcessRecord()
        {
            try
            {
                string freeDrive = CommonMethods.GetFreeDriveLetter();

                this.WriteObject(freeDrive);
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001", ErrorCategory.NotImplemented, null));
            }
        }
    }

   //in CommonMethods.GetFreeDriveLetter method
      internal static string GetFreeDriveLetter()
        {
            string freeDrive = "";
            string[] driveLetters = { "D:", "E:", "F:", "G:", "H:", "I:", "J:", "K:", "L:", "M:", "N:", "O:", "P:", "Q:", "R:", "S:", "T:", "U:", "V:", "W:", "X:", "Y:", "Z:" };
            var drives = System.IO.DriveInfo.GetDrives().Select(x => x.Name.Replace("\\", ""));
       
            foreach (var s in driveLetters.Reverse())
            {
                if (drives.Contains(s))
                {
                    freeDrive = "";
                }
                else
                {
                    freeDrive = s;
                    break;
                }
            }

            return freeDrive;
        }

For map and unmap I used Windows Script Host object model reference(IWshRuntimeLibrary)

     [Cmdlet("Map","AuthNetworkDrive")]
    public class MapNetworkDrive: PSCmdlet
    {
        [Parameter(Mandatory=true, Position=0,ValueFromPipeline=false)]
        public string UNCPath { get; set; }

        [Parameter(Mandatory=false, Position=1)]
        public PSCredential Credential { get; set; }

        protected override void ProcessRecord()
        {
            try
            {
                WshNetwork network = new WshNetwork();
                if (Credential == null)
                {
                    network.MapNetworkDrive(CommonMethods.GetFreeDriveLetter(), UNCPath, false);
                }
                else
                {
                    network.MapNetworkDrive(CommonMethods.GetFreeDriveLetter(), UNCPath, true, Credential.UserName, Credential.GetNetworkCredential().Password);
                }
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001",ErrorCategory.MetadataError, null));
            }
        }
    }

    [Cmdlet("Map", "DisconnectNetworkDrive")]
    public class UnMapNetworkDrive : PSCmdlet
    {
        [Parameter(Mandatory=true, Position=0)]
        public string DriveName { get; set; }

        protected override void ProcessRecord()
        {

            try
            {
                
                    IWshRuntimeLibrary.WshNetwork network = new IWshRuntimeLibrary.WshNetwork();
                    network.RemoveNetworkDrive(DriveName, true, true);
                
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001", ErrorCategory.MetadataError, null));
            }
        }
    }

Once the build, you can import the module from powershell ise

Import-Module 'module dll path'

this will be available for that session. One can copy to the powershell module path, so that it can be available all the time.

Powershell – Basics 4

lets talk about the variables

# All variables start with a $. Show a simple assignment
$hi = "Hello World"

#Print the Value
$hi

Write-Host $hi

# Show the type
$hi.GetType()

#Types oare mutaple
Clear-Host
$hi = 5
$hi.GetType()

Clear-Host
[System.Int32]$myint = 42 # Can make strongly typed variables
$myint
$myint.GetType()

$myint = "This won't work will raise an exception"

# There are shortcuts for most .net types
clear-host
[int] $myotherint = 42
$myotherint.GetType()

[string] $mystring = "hansy"
$mystring.GetType()

# Others include short, float, decimal, single, bool, byte, etc

(42).GetType() # Not just varibles are types
"Hansy is cool".GetType()

# Accessing methods on objects
"Hansy is Cool".ToUpper()
"Hansy is cool".Contains("is")

# comparisons
$var = 42
$var -gt 40
$var -lt 40
$var -eq 42

# List is
# -eq Equals
# -ne not equal to
# -lt less than
# -gt Greater than
# -le Less than or equal to
# -ge Greater than or equal to

# -Like        Like wildcard pattern matchin
# -NotLike     Not like
# -Match       Matches based on regular expressions
# -NotMatch    Non-matches based on regular expressions

# Calculations are like any other language
$var = 3*11 # Also uses +, -, and /
$var

$var++ # supports unary operators ++ and --
$var

#implicit Type conversions
"43" -eq 42
42 -eq "42"

# Whatever is on the right is converted to the data type on the left
# can lead to some odd conversions
42 -eq "042" # True because the string is converted to int
"042" -eq 42 # False because the int is converted to string


#--------------------------------------------
# Using the *-Variable cndlets
#--------------------------------------------

Clear-Host

#normal variable usage
$normal = 33
$normal

$text = "in the morning"
$text

# Long version of $var = 123
New-variable -Name var -Value 123
$var

#Displays the variable and it's values
Get-Variable var -valueonly

Get-Variable var

Get-Variable # Without Patams it shows all variables

# Assign a new vale to an existing variable
# $var = 789
Set-Variable -Name var -value 789
$var

#clear the contents of a variable
# same as $var = null
Clear-variable -Name var
# After a clear you can still access $var, but it has no value
$var

#Wipe out a varilable
Remove-variable -Name var
# Now var is gone if you try to remove or clear again an error occurs
# (note if you try to access it by just doing a $var the var is recreated)

Get-Variable var # now produces an error

$var # recreates the object


#------------------------------------------
# String Handling
#------------------------------------------

# String Quoting
Clear-Host

"This is a string"
'This is a string too!'

# Mixed Quoted
'I just wanted to say "Hello World", OK?'
"I can't believe how cool powershell is!"

# You can also double quote to get quot3s in strings
"I just wanted to say ""Hello World"", OK?"
'I can''t believe how cool powershell is!'

#Escape sequences - use the backtick `
Clear-host
# backspace `b (have to show in rea window)
"hans`braj"

# newline `n
"Hans`nraj"

# carriage return `r (doesn't really show anything)
"Hans`sraj"

# crlf `r`n
"hans`r`nraj"

# tabs
"hans`traj"


# Here strings for large blocks of text----------------
clear-host
$hertext=@"
Some text here
more here and little
    bit more here

and a blank line above
"@

$hertext

# the @ and quote must be last on starting line then first on ending line
# also works with single quotes

$morehertext =@'
Some more text here
to test with single
   quote
   
 using a blank line too!.
'@
 
 # note how the nexted ' is handled ok, no double quoting needed

 $morehertext
# String interpolation
clear-host
$items = (Get-ChildItem).Count
$loc = Get-Location
"There are $items items are in the folder $loc" 

# To actually display the variable, excape it with a backtick
"There are `$items items are in the folder `$loc."

# String interpolation only works with double quotes
'There are $items items are in the folder $loc '

# It does work with here strings
$hereinterpolation = @"
Items`tFolder
-----`t------------
$items`t$loc

"@

$hereinterpolation

# Can use expressions in strings, need to be wrapped in $()
clear-host
"There are $((Get-ChildItem).COunt) items are in the folder $(Get-Location)."

"The 15% tip of a 33.33 dollar bill is $(33.33 * 0.15) dollars."

#String Formatting -C# like syntax is supported
# In C you'd use:

[string]::Format("There are {0} items.", $items)

#Powershell shortuct
"There are {0} items." -f $items

"There are {0} items in the location {1}." -f $items, $loc

"The 12% tip of a 33.33 dollar bill is {0} dollars" -f (33.33 * 0.12)

"The 12% tip of a 33.33 dollar bill is {0:0.00} dollars" -f (33.33 * 0.12)

#Wildcards
clear-host
"Hansraj" -like "hans*"
"Hansraj" -like "some*"
"Hansraj" -like "?ansraj" # question marks work for single characters
"Hansraj" -like "hans*[a-j]"   # ends in a char berween a and j
"Hansraj" -like "hans*"   # ends in a char between c and s

# Regular expressions
clear-host
"231-334-1254" -match "[0-9]{3}-[0-9]{3}-[0-9]{4}"  #validdate phone number
"abc-334-1254" -match "[0-9]{3}-[0-9]{3}-[0-9]{4}" #validation fails
"231.334.1254" -match "[0-9]{3}-[0-9]{3}-[0-9]{4}" #validation fails


#---------------------------------------
# Arrays
#-----------------------------------------

# Simiple array
clear-host
$array = "some", "code"
$array[0]
$array[1]
$array

$array.GetType()

#Updating arrays
$array = "robert", "Rama"
$array

$array[0] = "roope"
$array[1] = "ssope"

$array

#Formal array creating syntax
$array = @("some", "code")
$array

$array = @() # only way to create an empty array
$array.Count

$array = 1..5 # Can load arrays using numeric range notation
$array

# Check to see if an item exists
clear-host
$numbers = 1, 42, 234
$numbers -contains 42

$numbers -notcontains 99

$numbers -notcontains 234

##

#----------------------------------------
# Hash Tables
#-----------------------------------------

$hash = @{"Key" = "Value";
           "Some" = "Code";
           "mcsft" = "Microsoft"}
$hash           #Displays all values
$hash["mcsft"]  # Get a single value for the key

$hash."mcsft" # Get a single value using object suntax

# You can use variables a keys
$mykey = "Some"
$hash.$mykey      #using variable as a property
$hash.$($mykey)   #Evaluating as an expression
$hash.$("So" + "me")

#Adding and removing values
$hash               #Here's what's there to start
$hash["Top Gear"] = "topgear.com"   # Add value using new key
$hash               #Show the additional row

$hash.Remove("Some")  # Remove by passing the key
$hash

# See if key exists
$hash.Contains("Top Gear")
$hash.Contains("Some")

$hash.ContainsValue("Code")
$hash.ContainsValue("Microsoft")

$hash.Keys
$hash.Values

$hash.Keys -Contains "mcsft"


##########--
### Built in variables
#########----

clear-host
set-location c:\New_folder
#Automatic variables

#False and true
$false
$true
#nUll
$null

# Current directory
$pwd

#Users HOme Direcotory
$home
#Info about a users machine
$host

# Process ID
$PID

#Info about the current version of powershell
$PSVersionTable

$_  # CurrentObject
Get-ChildItem | Where-Object {$_.Name -like "*.ps1"}

Powershell – Basics 3

If we look more into powershell programming

#---------------------------------------------------
# Functions
#---------------------------------------------------

# Functions are basically script blocks with names.
function write-fullname($firstName, $lastName)
{
    Write-host ($lastName + " , " + $firstName)
}

write-fullname "Kishore" "Patil"  //output: Patil, Kishore

# unlike other languages, you don't use () or ,
# Rather than using set-variable with its -scope, you can pass by ref
# Note however it turns it into an object, thus requiring the .Value syntax
function Set-fvar([ref] $myparam)
{
$myparam.Value = 33
}

clear-host
$fvar = 42
"fvar before: $fvar"
Set-fvar ([ref] $fvar) # Must add ref to call
"fvar after: $fvar"

# Read from pipeline
function Get-CoolFiles()
{
    begin {$retval = "Here are some cool files: `r`n"}
    process {
                if ($_.Name -like "*.ps1")
                    {$retval = $retval + "`t"+ $_.Name + "`r`n"}
                }
    end {return $retval}
}


clear-host
Get-ChildItem | Get-CoolFiles

# Above works but ties it to PS1


# Filters can be built to remove unwanted files
filter Show-PS1Files
{
    $filename = $_.Name
    if ($filename -like "*.ps1")
        { 
            return $_
         }
}

clear-host
Get-ChildItem | Show-PS1Files

# This Version doesn't check for ps1, it just lists what's passed in
function List-FileNames()
{
  begin {$retval = "Here are some cool files: `r`n"}
    process {
               $retval = $retval + "`t"+ $_.Name + "`r`n"
                }
    end {return $retval}
    
}

clear-host
Get-ChildItem | List-FileNames

#Now combine the two for real flexibility
Get-ChildItem | Show-PS1Files | List-FileNames

# Now to do other files, just create another filter
filter Show-textfiles
{
    $filename = $_.Name
    if ($filename -like "*.txt")
        { 
            return $_
         }
}


Get-ChildItem | Show-textFiles | List-FileNames

# Now you have two ways to use your functions
clear-host
Get-ChildItem | Show-PS1Files | List-FileNames
Get-ChildItem | Show-textFiles | List-FileNames

# Having your function output to the pipeline
clear-host
Get-ChildItem | Select-Object "Name"

function Get-ChildName()
{
    Write-output (Get-ChildItem | Select-Object "Name")
}

Get-ChildName | Where-Object {$_.Name -like "*.ps1"}

# Supporting -verbose and -debug options
# To support, first need to change the values of the special variables:
# $DebugPreference        Default is SilentlyContinue, change to Continue
# $VerbosePreference      Default is SilentlyContinue, change to Continue

function Get-ChildName()
{
    param([switch]$verbose, [switch]$debug)
    
    if ($verbose.IsPresent)
    { $VerbosePreference = "Continue"} 
    else
    {$VerbosePreference = "SilentlyContinue"}   
    if ($debug.IsPresent)
    {
        $DebugPreference = "Continue"
    }
    else
    {
        $DebugPreference = "SilentlyContinue"
    }
    
    
    write-verbose "Current working location is $(Get-Location)"
    write-output (Get-ChildItem | Select-Object "Name")
    write-debug "OK I've selected some."
}

clear-host
Get-ChildName
Get-childname -verbose
Get-childName -debug
Get-ChildName -verbose -debug


#-------------------------------------------------------
# Adding help to your functions
#-------------------------------------------------------

clear-host
get-help get-childname

#Custom tags within a comment block that Get-Help will recognize
# Note that not all of them are required
# .SYNOPSIS        - A brief description of the command
# .DESCRIPTION     - Detailed command description
# .PARAMETER name  - Include one description for each parameter
# .EXAMPLE         - Detailed examples on how to use the command
# .INPUTS          - What pipeline inputs are supported
# .OUTPUTS         - What this function outputs
# .NOTES           - Any misc notes you haven't put anywhere else
# .LINK            - A link to the URL for more help. Use one .Link tag per URL
# Use "Get-Help about_comment_based_help" for full list and details

function Get-ChildName()
{
<#
    .SYNOPSIS
    Returns a list of only the names for the child items in the current location.
    
    .DESCRIPTION
    This function is similar to Get-ChildItem, except that it returns only the name property.
    
    .INPUTS
    None.
    
    .OUTPUTS
    System.String. sends a collection of strings out of the piepeline.
        
#>

    Write-output (Get-ChildItem | Select-Object "Name")
}


clear-host
get-help get-childname


clear-host
get-help get-childname -full

#---------------------------------------------------------------
# Error handling
#---------------------------------------------------------------

function divier($enum, $denom)
{
    Write-Host "Divier begin"
    $result = $enum / $denom
    Write-host "Result: $result"
    Write-Host "Divier done."
}

clear-host
divier 33 11

divier 33 0

function divier($enum, $denom)
{
    Write-Host "Divier begin"
    $result = $enum / $denom
    Write-host "Result: $result"
    Write-Host "Divier done."
    trap
    {
        write-host "oh no! An error has occured !!"
        write-host $_.ErrorId
        write-host $_.Exception.Message
        continue # Continue will continue with the next line of code after the error
    }
}

clear-host
divier 33 0

function divier($enum, $denom)
{
    Write-Host "Divier begin"
    $result = $enum / $denom
    Write-host "Result: $result"
    Write-Host "Divier done."
    trap
    {
        write-host "oh no! An error has occured !!"
        write-host $_.ErrorId
        write-host $_.Exception.Message
        break # With break, or omitting it, error bubbles up to parent
    }
}

clear-host
divier 33 0

function divier($enum, $denom)
{
    trap [System.DivideByZeroException]
    {
        write-host "Hey, chowderhead, you can't divide by zero!"
        continue
    }
     trap
    {
        write-host "oh no! An error has occured !!"
        write-host $_.ErrorId
        write-host $_.Exception.Message
        break # With break, or omitting it, error bubbles up to parent
    }
    Write-Host "Divier begin"
    $result = $enum / $denom
    Write-host "Result: $result"
    Write-Host "Divier done."
   
}

clear-host
divier 33 0

# Two main ways to handle errors
# Option 1 - Handle error internally - see above function

# option 2 - Add trap logic in parent

# Change continue to break
function divier($enum, $denom)
{
    trap [System.DivideByZeroException]
    {
        write-host "Hey, chowderhead, you can't divide by zero!"
        break
    }
     trap
    {
        write-host "oh no! An error has occured !!"
        write-host $_.ErrorId
        write-host $_.Exception.Message
        break # With break, or omitting it, error bubbles up to parent
    }
    Write-Host "Divier begin"
    $result = $enum / $denom
    Write-host "Result: $result"
    Write-Host "Divier done."
   
}

# Now call routine in a script block or other function
& {
clear-host
divier 33 0

# Assume child has handled error, keep goin silently
trap
{ continue }

}

#-----------------------------------------------------------#
# Working with files
#-----------------------------------------------------------#
clear-host
Get-ChildItem "?.txt"

Get-Content "a.txt"
$a = Get-Content "a.txt"

clear-host
$a

# Looks are decptive, this actually an array
$a[0]
$a[1]

$a.GetType()

clear-host
for($i =0;$i -le $a.Count;$i++)
{$a[$i]}

# To combine, we can use join, passing in the seperator and the variable
$seperator = [System.Environment]::NewLine # could have done `r`n
$all = [string]::Join($seperator, $a)

$all

$all.GetType()  # string

# Supports wildcards
$courses = Get-content "?.txt"
$courses

$allcourses =[string]::Join($seperator, $courses)
$allcourses

# To write things to disk, use set-content

# Just to prove it's not there
Get-ChildItem "All Courses.txt"

set-content -value $allcourses -path "All Courses.txt"

Get-Content "All Courses.txt"

# Set-Content is destructive!!! If the file exists it's overwritten
Set-Content -Value "Powershell" -Path "All Courses.txt"
Get-Content "All Courses.txt"

# To append, use add-content
set-content -value $allcourses -path "All Courses.txt" # Recreate file
Get-Content "All Courses.txt"


Add-Content -Value "Powershell" -Path "All Courses.txt"
Get-Content "All Courses.txt" # Show it again with new course

# clean up afterward
Remove-item "All courses.txt"

# csv files
# use it to save objects

Get-process | Export-CSV "Processes.csv"

# And then read them
$header = "_NounName", "Name", "Handles", "VM", "WS", "PM", "NPM", "Path", "Company", "CPU", "FileVersion", "ProductVersion", "Product"
$processes = Import-CSV "Processes.csv" -Header $header
$processes

# XML Files
# Create an XML Template
$courseTemplate = @"
<courses version="1.0">
    <course>
        <name></name>
        <level></level>
    </course>
</courses>
"@

$courseTemplate | Out-File "C:\Users\Kpatil\documents\Powershell_Tut\somecourses.xml"

# Create a new xml variable and load it from the file
$courseXml = New-Object xml
$courseXml.Load("C:\Users\kpatil\documents\Powershell_Tut\SomeCourses.xml")

# Grab the template
$newCourse = (@($courseXml.courses.course)[0]).Clone()

#Loop over the collection from CSV and add them to the xml
$header = "Course", "Level"
$coursecsv = Import-Csv "All Courses.csv" -Header $header

for($i=0;$i -lt $coursecsv.Count;$i++)
{
    $newCourse = $newCourse.Clone() # copy the previous object, or for the first time copy the template
    $newCourse.Name = $coursecsv[$i].Course
    $newCourse.Level = $coursecsv[$i].Level
    $courseXml.Courses.AppendChild($newCourse) > $null # If you don't redirect to Null it echos each appen
}

#Remove the template since we now have data
$courseXml.Courses.Course |
    Where-Object {$_.Name -eq ""} |
    ForEach-Object {[void]$courseXml.Courses.RemoveChild($_)}

# Save to Xml file
$courseXml.Save("C:\Users\kpatil\documents\Powershell_Tut\SomeCourses.xml")

# Open it up and show as a plain text file
$textxml = Get-content "C:\Users\kpatil\documents\Powershell_Tut\SomeCourses.xml"
$textxml

# Open it up and work with it as an xml file
$mycoursesxml = get-content "C:\Users\kpatil\documents\Powershell_Tut\SomeCourses.xml"
foreach($course in $mycoursesXml.courses.course)
{
    Write-host "The course" $course.Name "is a Level" $course.Level "course."
}

Powershell – Basics 2

If we look more into powershell, like conditional statements and looping like (if..else, switch, while) just like in .Net basically syntax looks similar to c#

#----------------------------
# Conditional statements
#---------------------------

Clear-Host
#Condition - if/else
$var = 2
if ($var -eq 1)
{
Clear-Host
"If loop"
}
else
{
clear-host
"else loop"
}

# if elseif
if($var -eq 1)
{
 clear-host
 "If -eq 1 loop"
}
else
{
    if ($var -eq 2)
    {
    clear-host
    "If -eq 2 loop"
    }
    else
    {
    clear-host
    "else else loop"
    }
}

#Switch statement for multiple conditions
clear-host
$var = 43 #Also test with 43 and 49

switch ($var)
{
    41 {"Forty one"}
    43 {"Forty three"}
    49 {"Forty nie"}
    default {"Fifty"}
}


#Will match all lines that match
clear-host
$var = 42
switch($var)
{
    42 {"Forty two"}
    "42" {"Forty Two string"}
    default {"default"}
}

#To Stop processing once a block is found use break
clear-host
$var = 42
switch($var)
{
    42 {"Forty two";break}
    "42" {"Forty Two string";break} 
    default {"default"}
}

#Swtich works with collections, looping and execyting for each match
clear-host
switch (3,1,2,42)
{ 
1 {"One"}
2 {"Two"}
3 {"Three"}
default {"The default answer"}
}

# String compares are case insensitive by default
clear-host
switch ("Some")
{
    "some" {"lowercase"}
    "SOME" {"UpperCase"}
    "Some" {"Mixedcase"}
}

# Use the -casesensitive switch to make it sensitive
clear-host
switch -casesensitive ("Some")
{
  "some" {"lowercase"}
    "SOME" {"UpperCase"}
    "Some" {"Mixedcase"}
}

# Supports wildcards
clear-host
switch -Wildcard ("Some")
{
  "so*" {"*"}
    "?ome" {"?"}
    "So??" {"???"}
}

# Note it will also support regex matches

##

#-----------------------------------------------------------
# Looping
#-----------------------------------------------------------

#while
clear-host
$i = 1
while ($i -le 5)
{
    "`$i = $i"
    $i = $i +1
}

# won't execute if condition is already true
clear-host
$i = 6
while ($i -le 5)
{
    "`$i = $i"
    $i = $i +1
}


#Do
clear-host
$i = 1
do
{
    "`$i = $i"
    $i++
}while ($i -le 5)

# Do will always execute at least once
clear-host
$i = 6
do
{
    "`$i = $i"
    $i++
}while ($i -le 5)

# Use until to make the check more positive
clear-host
$i = 1
do
{
    "`$i = $i"
    $i++
}until ($i -gt 5)

# For loop iterate a number of times
clear-host
for ($f =0;$f -le 5;$f++)
{
    "`$f = $f"
}

#Note the initializer can be set seperately
clear-host
$f=1
for (;$f -le 5;$f++)
{
    "`$f = $f"
}

# Iterating over a collection 1 by 1
clear-host
$array = 11,12,13,14,15  # Simple array
for ($f =0;$f -lt $array.Length ;$f++)
{
    "`$array[$f] =" +$array[$f]
}

# foreach works on a collection
clear-host
$array = 11,12,13,14,15  # Simple array
foreach ($item in $array)
{
    "`$item = $item"
}

# foreach works with an array of objects
clear-host
$array = 11,12,13,14,15  # Simple array
foreach ($item in Get-ChildItem)
{
  $item.Name
}

# Combine with if to give a better focus
clear-host
set-location "C:\Users\kpatil\Documents\Powershell_Tut"
$array = 11,12,13,14,15  # Simple array
foreach ($item in Get-ChildItem)
{
    if($item.Name -like "*.ps1")
    {
        $item.Name
     }
}

# Use break to get out of the loop
clear-host
set-location "C:\Users\newuser\Documents\Powershell_basics"
$array = 11,12,13,14,15  # Simple array
foreach ($item in Get-ChildItem)
{
    if($item.Name -like "*.ps1")
    {
        $item.Name
        break # Exits the loop on first hit
     }
}

# Use continue to skip the rest of a loop but got onto the next iteration
clear-host
set-location "C:\Users\newuser\Documents\Powershell_Tut"
foreach ($item in Get-ChildItem)
{
    if($item.Name -like "*.ps1")
    {
        $item.Name
        continue # 3xits the loop on first hit
     }
     "This isn't a powershell command: $item"
}

# When used in a nested loop, break exits to the outer loop
clear-host
foreach ($outside in 1..5)
{
"`$outside = $outside"
    foreach($inside in 6..9)
    {
        "   `$inside = $inside"
        break
    }
}

# Use loop labels to break to a certain loop
clear-host
:outsideloop foreach ($outside in 1..5)
{
"`$outside = $outside"
    foreach($inside in 6..9)
    {
        "   `$inside = $inside"
        break outsideloop
    }
}

# Using continuew inside an inner loop
clear-host
foreach ($outside in 1..5)
{
"`$outside = $outside"
    foreach($inside in 6..9)
    {
        "   `$inside = $inside"
        continue
        "this will never execute as continue goes back to start of inner for loop"
        #note, because we continue to the inside loop, the above line
        # will never run but it will go through all itereations of the inner loop
    }
}

clear-host
:outsideloop foreach ($outside in 1..5)
{
"`$outside = $outside"
    foreach($inside in 6..9)
    {
        "   `$inside = $inside"
        continue outsideloop
        "this will never execute as continue goes back to start of inner for loop"
        #here, because we break all the way to the outer loop the last two
        # iterations (8 and 9) never run
    }
    "this will never run too"
}

##

Powershell – Basics

It’s very interesting to learn and work with powershell. It’s very powerful and uses most of the Microsoft .Net Class Library. If we look at the basics

#Get-Command - Retrieves a list of all powershell commands
Get-Command

# Can expand by searching for just a verb or noun
Get-Command -verb "get"
Get-Command -noun "service"

# Get-Help can be used to explain a command
Get-Help Get-Command
Get-Help Get-Command -examples
Get-Help Get-Command -detailed
Get-Help Get-Command -full

#Most Command can also be passed a -? parameter to get help
Get-Command -?

#Moving around the file tree
#Get-ChildItem list all items in current path
Get-ChildItem

# set-Location will change the current path
Set-Location c:\app
Set-Location "C:\New_folder\"

# Pipelining -combine CmdLets for Power
Get-ChildItem | Where-Object {$_.Length -gt 1kb }

Get-ChildItem | Where-Object {$_.Length -gt 1kb } | Sort-Object Length

#Can break commands up among several lines
# (note pipe must be last char on line)
Get-ChildItem |
    Where-Object {$_.Length -gt 1kb } |
    Sort-Object Length
    
#To Specify columns in the output and get nice formatting, use Format-Table
Get-ChildItem |
    Where-Object {$_.Length -gt 1kb } |
    Sort-Object Length |
    Format-Table -Property Name, Length -AutoSize

#You can also use the Select-Object to retrieve certain properties from an object
Get-ChildItem |
    Select-Object Name, Length | Where-Object {$_.Length -gt 1kb }|
    Sort-Object Length
    
# .Net Everywhere
$str = "I am now a powershell novice"
$str            //Gets the string
$str.Length     //Gets the length of the string
$str.GetType()  //String