Showing posts with label Powershell. Show all posts
Showing posts with label Powershell. Show all posts

Wednesday, August 28, 2013

Send email using Powershell

Sending an email using Powershell couldn't be easier. You just need to use the Send-MailMessage commandlet.

It is used as follows.

Send-MailMessage
 -From "ReubenBartolo@test.com"
-To "ReubenBartolo@test.com"
-Subject "Hello"
-Body "World"
-SmtpServer "mail.test.com"


To add more than one recepient, just add as follows.

-To "Receiver1@test.com","Receiver2@test.com"

Thursday, August 22, 2013

Force Powershell to always create an array

Imagine you have a file called buildLog.txt, which contains

1
2
3
22

Now, also imagine you want to find out if a line contains a specific number in this text file.

You can run a command like this:


$allWarnings = Select-String build.log.txt -Pattern "2"  | Select-Object Line,LineNumber,FileName | Sort-Object -Property Line -Unique ; if ($allWarnings.Count -gt 0) { $allWarnings | Format-List; }

This works correctly and returns:

Line       : 2
LineNumber : 2
Filename   : build.log.txt

Line       : 22
LineNumber : 4
Filename   : build.log.txt


But if you run it to check if any sentences contain a 1, something weird happens:

$allWarnings = Select-String build.log.txt -Pattern "1"  | Select-Object Line,LineNumber,FileName | Sort-Object -Property Line -Unique ; if ($allWarnings.Count -gt 0) { $allWarnings | Format-List; }

This returns no results. This is very weird and unexpected behaviour, to say the least. But the reason can be understood once you break the steps down.

In the first case, we have multiple results, which creates an array. Then we do a .Count on this array, and we get the result.
In the second case, we only have one result. This is an object, and not an array. Therefore this has no .Count property, so .Count will return null.

The fix is luckily very easy. Simply force the result to always be an array. This is done by simply adding one keyword in front.

[array]$allWarnings = Select-String build.log.txt -Pattern "1"  | Select-Object Line,LineNumber,FileName | Sort-Object -Property Line -Unique ; if ($allWarnings.Count -gt 0) { $allWarnings | Format-List; }

This now works as expected.


Line       : 1
LineNumber : 1
Filename   : build.log.txt


Success!

Monday, January 14, 2013

Which .Net Version is my Powershell using?

To discover which .Net version your Powershell console is using, simply insert the following command:


[System.Reflection.Assembly]::GetExecutingAssembly().ImageRuntimeVersion

Load .Net 4 Dll From Powershell

Powershell 2 by default uses .Net 2. This means that if you try to load a DLL made in .Net 4 from Powershell 2, you will get the the following error.

Add-Type : Could not load file or assembly '' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

This can be solved as follows:


  1. Locate the Powershell executable. This is either under C:\Windows\System32\WindowsPowershell\v1.0 in a 32-bit machine, or C:\windows\SysSOS64\WindowsPowerShell\v1.0 in a 64-bit machine.
  2. Check if a file called PowerShell.exe.config exists. If it does, edit it. If it does not, create it.
  3. Make sure this config file contains these lines.

<?xml version="1.0"?> 
<configuration> 
    <startup useLegacyV2RuntimeActivationPolicy="true"> 
        <supportedRuntime version="v4.0.30319"/> 
        <supportedRuntime version="v2.0.50727"/> 
    </startup> 
</configuration>



Wednesday, November 21, 2012

Powershell Format String with -F

Using String.Format in Powershell is very easy. Simply do as follows:

" My Name is {0} and I am {1} years old" -f  "Reuben", "27"

This will output

My Name is Reuben and I am 27 years old.

We can also add operators to transform the string. Below is a table.

OperatorExampleResultsDescription

{0}Display a particular element"{0} {1}" -f "a", "b"a b
{0:x}Display a number in Hexadecimal"0x{0:x}" -f 1813420x2c45e
{0:X}Display a number in Hexadecimal uppercase"0x{0:X}" -f 1813420x2C45E
{0:dn}Display a decimal number left justified, padded with zeros"{0:d8}" -f 300000003
{0:p}Display a number as a percentage"{0:p}" -f .12312.30 %
{0:c}Display a number as currency"{0:c}" -f  12.34$12.34
{0,n}Display with field width n, left aligned"|{0,5}|" -f "hi"|   hi|
{0,-n}Display with field width n, right aligned"|{0,-5}| -f "hi"|hi   |
{0:hh}
{0:mm}
Display the hours and minutes from a date time value"{0:hh}:{0:mm}" -f (Get-Date)01:34
{0:C}Display using the currency symbol for the current culture"|{0,10:C}|" -f 12.3|    $12.40|



Reference:
http://msdn.microsoft.com/en-us/library/26etazsy(VS.71).aspx

Monday, July 9, 2012

Call application from Powershell, and wait for it to finish

Start-Process -wait ./MyScript.cmd

Check if service is installed in Powershell

Recently I needed to check if IIS was installed on a machine using Powershell.

The obvious way of doing this is:

$iis = Get-Service W3SVC

if ($iis -eq $NULL)
{
"IIS not found"
}


The problem with this is that it does not really work, since the first line will crash if the service is not found.
The solution for this is to make it fail silently.


$iis = Get-Service W3SVC -ErrorAction SilentlyContinue
if ($iis -eq $NULL)
{
"IIS not found"
}

This makes it fail silently, and the code works as expected!

Wednesday, June 13, 2012

Finding MD5 of file in Powershell

You can find the MD5 of a file within Powershell using just a one liner. Here goes:

[BitConverter]::ToString((new-object Security.Cryptography.MD5CryptoServiceProvider).ComputeHash((new-object IO.FileInfo("c:\Path\ToFile.exe")).OpenRead())).Replace("-","").ToLower()

Saturday, March 24, 2012

Powershell 32 or 64 bits

A weird issue can occur in PowerShell, when it comes to installing using InstallUtil on a 64 bit machine. InstallUtil might install within the 32-bit registry part, and PowerShell will then look for the cmdlet within the 64-bit.

It is useful to find out which version of PowerShell one is running. This can be done programmatically as follows.


if ([IntPtr]::Size -eq 4){
set-alias installutil $env:windir\Microsoft.NET\Framework\v2.0.50727\installutil
}else{
set-alias installutil $env:windir\Microsoft.NET\Framework64\v2.0.50727\installutil
}

Monday, March 19, 2012

Use C# as REPL

As a developer, sometimes we want to try something out quickly, to see if our idea works as a proof of concept. In the .Net environment this leads many times to many solutions on the desktop named ConsoleApplication1 and ConsoleApplication2, or WinformApplication1, with a form containing only one big button with the text Run! on it.

It is much more convenient to have something like Python has, where one can simply insert the code one line at a time, and see what the output is. This is known as REPL, which stands for Read-Eval-Print-Loop.

There are two ways which I know of how this can be achieved.

The first one is by means of PowerShell. This gives you the option of typing in C# code, and getting results immediately. The problem with this approach is that the code can loook quite different, where DateTime.Now can become [DateTime]::Now.



The second way is by making use of the wonderful tool which is part of the Mono Project.  Mono is an open source implementation of the .Net framework, and it can run on multiple operating systems.
This tool, called GSharp, can be found in the Mono Command Prompt. Simply type in csharp, and you are good to go.  Typing in DateTime.Now, now works.


Saturday, February 18, 2012

Open Explorer from Powershell in current folder

When working in powershell, it is very easy to open the current folder to be able to better work with the files within it.

Simply type in

Explorer .
(The dot should be typed also.)

And even shorter way is by typing

ii .

where the ii is short for Invoke-Item

Execution Policy in PowerShell


When you go to run a powershell script for the first time, it might fail. The reason is that by default the Execution Policy is set to not execute scripts (for security).

To check the current policy, type:

Get-ExecutionPolicy

The execution policies you can use are:

Restricted - Scripts won’t run.
RemoteSigned - Scripts created locally will run, but those downloaded from the Internet will not (unless they are digitally signed by a trusted publisher).
AllSigned - Scripts will run only if they have been signed by a trusted publisher.
Unrestricted - Scripts will run regardless of where they have come from and whether they are signed.
You can set PowerShell’s execution policy by using the following cmdlet:


To change the current policy, simply type:

Set-ExecutionPolicy <policy name>

Special Powershell commands


Measure-Object = Size of Result
Get-Member = Get object methods
Get-Help = Man Pages


How to Install your own PowerShell Cmdlets


set-alias installutil $env:windir\Microsoft.NET\Framework\v2.0.50727\installutil

## to call installer by typing installutil

installutil '.\Windows PowerShell Project.dll'

## Install your own DLL

get-PSsnapin -registered

## Check registered Snapins

add-pssnapin CmdletName

## Cmdlet is now added and ready to be used

Saturday, February 4, 2012

Difference between Cmdlet and PSCmdlet

As taken from MSDN:


Cmdlet Base Classes

Windows PowerShell supports cmdlets that are derived from the following two base classes.
  • Most cmdlets are based on .NET Framework classes that derive from the Cmdlet base class. Deriving from this class allows a cmdlet to use the minimum set of dependencies on the Windows PowerShell runtime. This has two benefits. The first benefit is that the cmdlet objects are smaller, and you are less likely to be affected by changes to the Windows PowerShell runtime. The second benefit is that, if you have to, you can directly create an instance of the cmdlet object and then invoke it directly instead of invoking it through the Windows PowerShell runtime.
  • The more-complex cmdlets are based on .NET Framework classes that derive from the PSCmdlet base class. Deriving from this class gives you much more access to the Windows PowerShell runtime. This access allows your cmdlet to call scripts, to access providers, and to access the current session state. (To access the current session state, you get and set session variables and preferences.) However, deriving from this class increases the size of the cmdlet object, and it means that your cmdlet is more tightly coupled to the current version of the Windows PowerShell runtime.

SwitchParameter


I was curious how one can create his own cmdlet, with parameters which do not take values.
For example, when a Cmdlet runs, we can specify -Verbose. This parameter does not take a value, it simply exists.

We do this by creating a parameter like this.

    private SwitchParameter hasHeader;
    [Parameter(Position = 1,
    Mandatory = false,
    ValueFromPipelineByPropertyName = true,
    HelpMessage = "Whether first row is a header"),
    ValidateNotNullOrEmpty()]
    public SwitchParameter HasHeader { 
              get { return hasHeader; } 
              set { hasHeader = value; }
      }

And then we check for it like this:

if (HasHeader.IsPresent){ };

It is important to note that the default value is false.

Typical pipeline cmdlets and functions


  • Cmdlet/Function         Description

  • Compare-Object         Compares two objects or object collections and marks their differences
  • ConvertTo-Html           Converts objects into HTML code
  • Export-Clixml             Saves objects to a file (serialization)
  • Export-Csv                 Saves objects in a comma-separated values file
  • ForEach-Object          Returns each pipeline object one after the other
  • Format-List                Outputs results as a list
  • Format-Table              Outputs results as a table
  • Format-Wide              Outputs results in several columns
  • Get-Unique                 Removes duplicates from a list of values
  • Group-Object              Groups results according to a criterion
  • Import-Clixml              Imports objects from a file and creates objects out of them (deserialization)         
  • Measure-Object          Calculates the statistical frequency distribution of object values or texts
  • more                          Returns text one page at a time
  • Out-File                      Writes results to a file
  • Out-Host                    Outputs results in the console
  • Out-Host -paging         Returns text one page at a time
  • Out-Null                      Deletes results
  • Out-Printer                  Sends results to printer
  • Out-String                   Converts results into plain text
  • Select-Object              Filters properties of an object and limits number of results as requested         
  • Sort-Object                 Sorts results
  • Tee-Object                  Copies the pipeline's contents and saves it to a file or a variable
  • Where-Object              Filters results according to a criterion

Good free Powershell book

I am currently reading this book about Powershell. It has some good examples, and very detailed explanations of how Powershell works.

Wednesday, February 1, 2012

Powershell Aliases

An Alias is simply a different way of doing the same task. So if you are used to other systems (e.g. CMD or Linux), you can most likely migrate that task. Below is a list of such tasks.


If the alias you wish does not exist, no problem. Here is how to create your own.

Set-Alias [-Name] [-Value]

If you want to see what Aliases you have set,

Get-Alias [[-Name] ]


PowerShell (Cmdlet)

PowerShell (Alias)

Get-ChildItem

gci, dir, ls

Get-Content

gc, type, cat

Get-Command

gcm

Get-Help

help, man

Clear-Host

cls, clear

Copy-Item

cpi, copy, cp

Move-Item

mi, move, mv

Remove-Item

ri, del, erase, rmdir, rd, rm

Rename-Item

rni, ren, mv

Get-Location

gl, pwd

Pop-Location

popd

Push-Location

pushd

Set-Location

sl, cd, chdir

Tee-Object

tee

Write-Output

echo, write

Get-Process

gps, ps

Stop-Process

spps, kill

Select-String

n/a

Set-Variable

sv, set




Searching for text files using Powershell

Below, one can admire the simplicity, power, and flexibility of Powershell.

Here are two ways of searching for all textfiles in your C Drive.

  • Get-Childitem C:\ -recurse -force | Foreach { IF ($_.extension -eq ".txt") { $_.name } }

  • Get-ChildItem C:\ -recurse -force | Where { $_.extension -eq ".txt" } | select $_.name