Wednesday, July 22, 2015

#87: Executing Encoded Commands in Powershell

Today, we will take a look how we can avoid displaying sensitive information to users in form of text. This approach does not apply to a hacker or cracker, but it will just avoid flashing secure info to common users.

I had a requirement to connect SQL Server instance using SQL Login. If you connect to any server using Windows authentication, passwords are never revealed, but using SQL Logins in your script reveals everything as plain text. Although the login to used will have limited permission on SQL Server, but still disaplying passwords as plain text was going difficult to me. In fact, it applies to any case, we should never put passwords directly to the script as plain text.
Now, problem is clear that we will go with encryption route or we will do something else.
In Powershell, we have feature to run commands as Base-64 string. We can use this feature since Powershell v1.0.

A complete demonstration here:




Please follow below steps to achieve it :

1. Convert the command line to a Base-64 string.

$CodeLine = 'Write-Host "Hidden secret code!"'
$UniCodeLine = [System.Text.Encoding]::Unicode.GetBytes($CodeLine) 
$HexCodeLine = [Convert]::ToBase64String($UniCodeLine) 
echo "$HexCodeLine"

Description:
Line #1 : It will get the command to be executed
Line #2 : It will convert your code into Unicode string
Line #3 : It will convert Unicode string to Base-64 string
Line #5 : It will display the string. Now, you can copy paste the output to your actual code.

2. Run the command as below :

$Passwd=powershell -EncodedCommand "VwByAGkAdABlAC0ASABvAHMAdAAgACIASABpAGQAZABlAG4AIABzAGUAYwByAGUAdAAgAGMAbwBkAGUAIQAiAA=="
& sqlcmd -E -S ABC\ABC -U "User1" -P $Passwd

Description:
Line #1 : Get the output from encoded command line using -EncodedCommand parameter. Store results to $Passwd. 
Line #2 : Run the sqlcmd to SQL Server instance and pass password as $Passwd
I repeat, this does not solve the security problem completely as Base-64 string can be converted to string, but it is secure upto certain extent.

Thanks for reading.

Sunday, June 14, 2015

#86 : Mastering Powershell

A free ebook of powershell is 'Mastering Powershell' written by Dr. Tobias. The book is written in a very simple language and gives a full glimpse of Powershell Programming.

 

Download
(Download link might change anytime, please search in google/bing if required)

I like the way of expression of this book. But I feel there are some portions where you feel like the book is unorganized and it looks like writer has so much to say but still so much is left over. It covers most of the portions of Powershell programming especially if you have started learning Powershell.

This book can also help you learning scripting skills. Whether you at advaced, intemediate or novice level of scripting, this book might be very useful to you. As this book is free of cost, you don't have to bother, do have a look.


Powershell-Tips Rating : 3/5

Thursday, June 11, 2015

#85 : Find ODBC Drivers installed on the host with Powershell

ODBC Drivers are generally installed on servers to allow communication with different database engines. You can use Powershell to get the list of ODBC drivers installed on the host.
You need to run Get-ODBCDriver cmdlet which will give you all the details.

Get-OdbcDriver

Name      : Microsoft Access-Treiber (*.mdb)
Platform  : 32-bit
Attribute : {Driver, APILevel, FileExtns, FileUsage...}
Name      : Driver do Microsoft Paradox (*.db )
Platform  : 32-bit
Attribute : {Driver, APILevel, FileExtns, FileUsage...}
Name      : Driver do Microsoft Excel(*.xls)
Platform  : 32-bit

...

The output might not be pleasant. If you think so, you can try the line below:
Get-OdbcDriver | ft Name

Name                                                                                                                                                                      
----                                                                                                                                                                      
Microsoft Access-Treiber (*.mdb)                                                                                                                                          
Driver do Microsoft Paradox (*.db )                                                                                                                                       
Driver do Microsoft Excel(*.xls)                                                                                                                                          
Microsoft Text Driver (*.txt; *.csv)                                                                                                                                      
Driver da Microsoft para arquivos texto (*.txt; *.csv)                                                                                                                    
....

Thanks for reading!

 

Wednesday, June 10, 2015

#84 : Difference between redirection operator and Out-File

Redirection operator can be used most of the scripting languages. If you use single redirection operator (>), it means create a file and write or overwrite the file with the string.
In Powershell, you can use them, but we have advantage of Out-File cmdlet. Let us try to see what is major difference. The difference is that redirection operator will always go with unicode character.

For example:
echo "Line - 1" > c:\temp\file.ps1 
echo "Line - 2" >> c:\temp\file.ps1 
It will generate a file with Unicode character set.

Repeating the same with Out-File :
echo "Line - 1" | Out-File c:\temp\file.ps1 -Encoding "ASCII" 
echo "Line - 1" | Out-File c:\temp\file.ps1 -Encoding "ASCII" -Append 
It will generate a file with ASCII character set.

Mind that we have use -Append in the second line. This will allow appending. Check yourself that what will happen if you don't use -Append switch.

There are below character sets possible with -Encoding option:
Unicode
UTF7
UTF8
UTF32
ASCII
BigEndian
Unicode
OEM

If you don't mention Encoding switch, Unicode will be taken as default.


Don't mix character set if you don't want to see unexpected graphics in file. For example, if you run below lines, you will understand what I mean.

echo "Som" > file.txt
echo "Som" | out-file .\file.txt -Encoding "ASCII" -Append

When you open file.txt, you would see first line written correctly and second line written in chinese. I have faced such situations where output is coming from multiple command line apps like osql and sqlplus and mixing them together created a real mess. The difficult part is that you can barely troubleshoot where problem is coming from. Try to stick to ASCII in my opinion.

Thanks for reading this article!
 

Tuesday, June 9, 2015

#83 : Save File Dialog with Powershell

This is continuation of previous article. In fact, there is no difference in save dialog and open file dialog. The difference if that here you can get message of replacing file. Save File dialog does not save anything, you have to save it yourself.

Below is the code for the same :

#----------------------------------------------------------------------------------------#
#-- Function Declaration 
#----------------------------------------------------------------------------------------#

function Save-File([string] $initialDirectory ) 

{

[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null

$OpenFileDialog = New-Object System.Windows.Forms.SaveFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "All files (*.*)| *.*"
$OpenFileDialog.ShowDialog() |  Out-Null

return $OpenFileDialog.filename
} 

#----------------------------------------------------------------------------------------#
#Usage : 
#----------------------------------------------------------------------------------------#

$File=Save-File "C:\temp\tips" 

if ( $File -ne "" ) 
{
echo "You choose FileName: $File" 
} 
else 
{
echo "No File was chosen"
}





Hope this article was useful for you. Thanks for reading!

Monday, June 8, 2015

#82 : Open File Dialog with Powershell

This is interesting that all GUI operations can be done with Powershell without any problem. Basically, most of the resources available to any .NET application applied to Powershell. This make Powershell more vast and limitless (in my opinion).

So, let's see the code which will be used to open a dialog. The requirement is simple, the script will show a dialog to open any file, if user has open a file then script will display file name or show if user has cancelled the dialog. I would suggest not to use this script for any scheduling or automated job as this will stuck your job till host reboot (I think).

#----------------------------------------------------------------------------------------#
#-- Function Declaration 
#----------------------------------------------------------------------------------------#

function Open-File([string] $initialDirectory ) 

{

    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null

    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.initialDirectory = $initialDirectory
    $OpenFileDialog.filter = "All files (*.*)| *.*"
    $OpenFileDialog.ShowDialog() |  Out-Null

    return $OpenFileDialog.filename
} 

#----------------------------------------------------------------------------------------#
#Usage : 
#----------------------------------------------------------------------------------------#

$File=Open-File "C:\temp\tips" 

if ( $File -ne "" ) 
{
    echo "You choose FileName: $File" 
} 
else 
{
    echo "No File was chosen"
}



 

Friday, June 5, 2015

#81 : String handling with Substring function

Substring function is available in nearly all the programming and scripting languages. This function is best suited for traversing each character or set of characters of string based on length and rank of character to start with. In fact, you can do chopping of certain string from the complete string. I have used substring a lot with T-SQL Programming. Let us take a look how substring can be used in Powershell.

1. Chop last three characters from a string using substring. If string is less than 3 character, return whole string.

#-------------------------------------------------------#
#--Function to find last three characters of a string --# 
#-------------------------------------------------------#

function chop-last-three([string]$str)
{
 if ( $str.length -ge 3 ) 
 {
  echo $str.substring($str.length - 3, 3) 
 } 
 else 
 {
  echo $str
 }
}


chop-last-three "ABCDEFGHIJKLMNOP" 



2. Chop first three characters of a string using substring. If string is less than 5 characters, return whole string.

#-------------------------------------------------------#
#--Function to find first three characters of a string --# 
#-------------------------------------------------------#

function chop-first-three([string]$str)
{
 if ( $str.length -ge 3 ) 
 {
  echo $str.substring(0, 3) 
 } 
 else 
 {
  echo $str
 }
}


chop-first-three "ABCDEFGHIJKLMNOP"

That's all for today. You may ask questions if you want.
Thanks for reading this article!

Thursday, June 4, 2015

#80 : Find difference in two dates with Powershell?

Sometimes we need to get this information like total time taken by script or total time a program ran. This is quite simple to get the difference between two dates if the data type is set to DateTime.

Below is a sample script for the same :
This script will show the difference in Seconds, Hours and Minutes. You can also go to even deeper such as milliseconds.

Function Get-DateDifference( [DateTime]$FromDate, [DateTime] $ToDate , [String]$OutputType ) 
{
 [int]$Output=-1
 
 if ( $FromDate -gt $ToDate ) 
 {
  echo "Error: [From date] should not be greater than [To Date]."
 }
 else 
 {
  Switch ( $OutputType )
  {
   "Seconds"  {  $Output=$($ToDate - $FromDate).TotalSeconds } 
   "Hours"  {  $Output=$($ToDate - $FromDate).TotalHours } 
   "Minutes"  {  $Output=$($ToDate - $FromDate).TotalMinutes } 
   
  }
  
  if ( $Output -ne -1 ) 
  {
   echo "$Output $OutputType"
  }
 }
}

$Date1=Read-Host "Enter the From Date"
$Date2=Read-Host "Enter the To Date"

Get-DateDifference -FromDate $Date1 -ToDate $Date2 -OutputType 'Seconds'


Hope this was helpful tip.
Enjoy learning Powershell!

Wednesday, June 3, 2015

#79 : Find Free Memory Status on a Computer

Today's tip is about getting the free space in memory on a computer. This can easily done with WMI. Let's take a look in a one-liner.

Get-WmiObject win32_operatingsystem  | select csname, FreePhysicalMemory, FreeSpaceInPagingFiles, FreeVirtualMemory

This can play a good role when you are writing a script which might consume too much of memory, you can plan the execution when memory usage is normal.

Enjoy!

Tuesday, June 2, 2015

#78 : Find who is logged in list of machines using Powershell

Recently, there were list of workstations assigned to our team. As there are many people working on those workstations, it was difficult to find who is logged in on which machine without asking. Finally, I ended with below script which can tell the same easily.

Below are steps for testing the script :

1. Create a directory, say WhoLoggedIn.
2. Create a file with name list.txt.
3. Use Notepad and edit list.txt and add all servers with one line for each server.
4. Create a Powershell script say WhoLoggedIn.ps1

Paste the code from below :

$THIS_SCRIPT_NAME=${myInvocation}.ScriptName
$SCRIPT_LOC=Split-Path -parent ${Script:THIS_SCRIPT_NAME}
 

$VALS=gc $SCRIPT_LOC\List.txt | where { $_ -match "^[1-9]" } | foreach { $_ + $(& query user /server:"$_")  }

$FINAL_VAL=$VALS | foreach { $_.replace("USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME  ","") } | foreach { $_.replace("  ", " ") }

echo $FINAL_VAL


Run the same and you will see results in proper format. I made a script which will log the same info into SQL Server using the same script. Choice is all yours what you do with it. My job is to give direction ...

Enjoy!

Monday, June 1, 2015

#77 : How to get directory size using Powershell?

A quick tip, to get the size of the folder, you can use below line :

"{0:N2}" -f ($(ls "c:\temp" -recurse | Measure-Object -property length -sum).sum /1MB)  + " MB"


Replace MB with KB if you want in KB.


"{0:N2}" -f ($(ls "c:\temp" -recurse | Measure-Object -property length -sum).sum /1MB)  + " MB"
 
Hope this was easy, right?
 

Saturday, May 30, 2015

#76 : Using Choice Box in Powershell

I got an interesting requirement to allow users choose from a list. The list will be dynamic and will display all items of the file in a drop down list.

Preparation:
1. Create an empty file called list.txt.
2. Add below entries to the file:
ABC
XYZ
PQR
RST
UVX
123
3. Create script and paste below code:

function showDialog([string]$file) 
{
 [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
 [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 

 $objForm = New-Object System.Windows.Forms.Form 
 $objForm.Text = "Choice-Box"
 $objForm.Size = New-Object System.Drawing.Size(300,200) 
 $objForm.StartPosition = "CenterScreen"

 $objForm.KeyPreview = $True
 $objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter") 
  {
   $x=$objListBox.SelectedItem;$objForm.Close()}
  })
  
 $objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape") 
  {$objForm.Close()}})

 $OKButton = New-Object System.Windows.Forms.Button
 $OKButton.Location = New-Object System.Drawing.Size(75,120)
 $OKButton.Size = New-Object System.Drawing.Size(75,23)
 $OKButton.Text = "OK"
 $OKButton.Add_Click({$x=$objListBox.SelectedItem;$objForm.Close()})
 $objForm.Controls.Add($OKButton)

 $CancelButton = New-Object System.Windows.Forms.Button
 $CancelButton.Location = New-Object System.Drawing.Size(150,120)
 $CancelButton.Size = New-Object System.Drawing.Size(75,23)
 $CancelButton.Text = "Cancel"
 $CancelButton.Add_Click({$objForm.Close()})
 $objForm.Controls.Add($CancelButton)

 $objLabel = New-Object System.Windows.Forms.Label
 $objLabel.Location = New-Object System.Drawing.Size(10,20) 
 $objLabel.Size = New-Object System.Drawing.Size(280,20) 
 $objLabel.Text = "Please choose any of the below :"
 $objForm.Controls.Add($objLabel) 

 $objListBox = New-Object System.Windows.Forms.ListBox 
 $objListBox.Location = New-Object System.Drawing.Size(10,40) 
 $objListBox.Size = New-Object System.Drawing.Size(260,20) 
 $objListBox.Height = 80

 $items = gc $file | where { $_ -ne "" }
 
 foreach ( $item in $items) 
 {
  [void] $objListBox.Items.Add($item)
  
 } 

 $objForm.Controls.Add($objListBox) 

 $objForm.Topmost = $True

 $objForm.Add_Shown({$objForm.Activate()})
 [void] $objForm.ShowDialog()

 $x

} 


showDialog .\list.txt 


Once your run it, you will get a popup like below:


That's it! You can see the value of $x can be used further in any place of your code.

Hope you liked this article. Send your comments and suggestions to me...
Enjoy!

Friday, May 29, 2015

#75 : How to run Powershell scripts from network location (UNC Path)?

In most of the cases, people ask questions if they can run the Powershell scripts from network location which is shared on multiple machines.

At first sight,  I would not suggest to do it as this is not recommended to run unsigned scripts, but requirement is always a requirement and I have seen people debating in a long mail chain when I say that something is not possible. Sometimes whole group is fighting with me one after another and using google search and all options to make me accept. Believe me, I don't believe in too much argument on any topic, but still I don't like to accept something which cannot be done or something which cannot be done perfectly.

I believe in correct usage of any technology, arguments and debates are other areas are not my areas of expertise. Anyways, for those who have been forced to do something and for those who has to do something because it has to be done.

You can use -ExecutionPolicy "Bypass" in the command line. Something like this :

For example, if you have script located at abc server's c:\abc.ps1, you can run statement like this:
Powershell.exe -ExecutionPolicy bypass \\abc\c$\abc.ps1

This will not ask any questions or input. Keep all such shared script at central location, create a share or map a drive, do whatever suits your environment.

Hope, you liked this article. Please do sent your suggestions and advises.

 

Thursday, May 28, 2015

#74 : How to get IP address from Host Name using Powershell?

There are multiple ways to get it. Some will suggest using ping.exe also. But below is the tested and clean approach to do it.

Replace your host name below and test it at your end :

function GetIPAddress([string] $HostName) 
{
 trap {
  return 0 
 }
 $IP_ADDRESS=$([System.Net.Dns]::GetHostAddresses("$HostName")).IPAddressToString
 return $IP_ADDRESS 

} 

echo $(GetIPAddress "ABCHOSTNAME")


Hope you like this tip, do write your comments and suggestions.
Life is good!

Wednesday, May 27, 2015

#73 : How to list all files in current directory and subdirectories using Powershell?

Sometimes, we need to work with numerous files located in certain location. We might need to perform some action or read some lines with those files. When the requirement is all about reading all files in directory and sub-directories, we can simply use ls in Powershell. (Run Get-Alias ls to know which cmdlet is called in background, skipping this so that you learn something more, those who know this can avoid it ;))

Every experiment starts with a small building block, so let's run ls with recursion :

ls -recurse


You see multiple directories, but this is not useful as you don't have much option to perform any task on them.

    Directory: B:\tst

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----         5/26/2015   6:08 AM            A
d----         5/26/2015   6:09 AM            B
-a---         5/26/2015   6:09 AM          0 file4.txt
-a---         5/26/2015   6:09 AM          0 file5.txt

    Directory: B:\tst\A

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         5/26/2015   6:08 AM          0 file1.txt

    Directory: B:\tst\B

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         5/26/2015   6:09 AM          0 file2.txt
-a---         5/26/2015   6:09 AM          0 file3.txt


Now, run the same command with little twist and then you will be able to much from output :

ls -Recurse | foreach { $_.FullName  }

The result is full list of files and you can perform more precise operations on them.
B:\tst\A
B:\tst\B
B:\tst\file4.txt
B:\tst\file5.txt
B:\tst\A\file1.txt
B:\tst\B\file2.txt
B:\tst\B\file3.txt

But, if you see the output above, you can see that directories are also there,  but your requirement might be only related with files or directories. So, let's get separate results for them.

List all Files recursively :
ls -Recurse | where { $_.PSIsContainer -eq $false } |  foreach { $_.FullName }

Output:
B:\tst\file4.txt
B:\tst\file5.txt
B:\tst\A\file1.txt
B:\tst\B\file2.txt
B:\tst\B\file3.txt

List all directories recursively :
ls -Recurse | where { $_.PSIsContainer -eq $true } |  foreach { $_.FullName }

Output:
B:\tst\A
B:\tst\B

So, this concludes today's tip. Always start with small example and keep trying till you get the results. Send your mails and comments and let me know if you have questions.

Enjoy!


 

Tuesday, May 26, 2015

#72 : How to run a program with different credential in Powershell?

There are multiple ways to achieve it. I will suggest using a Get-Credential cmdlet to get the credential and use start-process to run the script or program of your choice. You can also use invoke-command for this purpose to run commands on remote machines of you network, but the approach is not advisable when WinRM is not enabled and I don't want to make it complicated.

So, let's take a look on the script and then we will see how it runs :

$c=Get-Credential
Start-Process c:\windows\notepad.exe -Credential $c

When you run the two lines above, you see a popup which asks your credentials :


Enter credential and then you will see the notepad.exe running with that credential.

This may help you if you are making a program which requires special credentials at some point and user can enter the login and password. Good for any interactive script only. We can also save the credentials and use that. We will see that in next article, till then enjoy!

Wednesday, May 13, 2015

#71 : Pause a Powershell Script

Sometimes, we need to pause scripting where any asynchronous operation is in progress or we have to wait for some file to appear. In all such cases, Start-Sleep can help you achieve that. Let's take a look into syntax and then we will use the same in our example :

Syntax:
Start-Sleep -Milliseconds <int> [<CommonParameters>]
Start-Sleep [-Seconds] <int> [<CommonParameters>]


Example:
Pause the script for 5 seconds:
Start-Sleep -Seconds 5

 

Tuesday, May 12, 2015

#70 : Show statistical information using Powershell

Today' we will talk about Measure-Object cmdlet which helps you peforming average, max, min and other operations. Before we perform some tests, we need to create a file with some data. My file is as follows :

name,age
Som,25
Ravi,30
Akash,60
Jack,89
John,16


Save the above as file.csv. You can use below command to see the statistics :

import-csv C:\engg.demo\file.csv | measure-object age -ave -max -min

Output:
Count    : 3
Average  : 38.3333333333333
Sum      :
Maximum  : 60
Minimum  : 25
Property : age


In measure-object, we mentioned the column name against which you want to run certain operation. After that, you can mention from below :
-ave : Average
-min : Min
-max : Max
-sum : Sum

Enjoy scripting!!

 

Sunday, May 10, 2015

#69 : Formatted output from a number with decimal using Powershell

Sometimes, we need to produce formatted output from a number with decimals. If the output has to be in a designated formatted such as till two places after decimals, we can simply format them using below. It helps specifying the precision correctly :

Below is the function to help you in setting precision till whatever places of decimal you want. If number is limited to only two digits after decimal, it will add zero as suffix, so this might help in some other cases also where you want to show result in money.

Please check the Gist below :



There are several other ways to do it, but I found it more flexible.
Enjoy scripting !!

Saturday, May 9, 2015

#68 : Understanding Try-Catch-Finally Blocks in Powershell

Try-Catch-Finally is language construct introduced in Powershell v2.0. It provides option to error handling in an elegant manner. While a faulty code might stop flow of your code, Try-Catch can be used to handle some of the obvious errors. For example, if you are writing to a file and suddenly disk got full, your script will fail miserably and error could be trapped further. The script will proceed further without having finishing pervious operation correctly. In a simple language, we can say that Try-Catch gives option to handle errors during runtime without impacting the desired flow of script.

(There are so many big articles written on this subject, this article is just a jump start. My intention is not re-invent the wheel.)


Below is a simple example using this language construct :
(It will run a divide-by-error operation and cause failure. The error will be forwarded on screen)



Enjoy developing Powershell scripts!




 

Friday, May 8, 2015

#67 : Get Windows Operating System Name and Version

Sometimes, we need to know the Operating system name and version for troubleshooting and sometimes we need to run specific code for specific version. With Powershell, this is very simple.

$OS_VERSION=$(Get-WmiObject -Class Win32_OperatingSystem).Version
$OS_NAME=$(Get-WmiObject -class Win32_OperatingSystem).Caption

echo "Version : $OS_VERSION"
echo "Version : $OS_NAME"


Hope, this was simple and useful for your scripts.
Enjoy scripting!!

Thursday, May 7, 2015

#66 : Formatted Date and Time Output

Mostly, in course of scripting, we need to display date and time in a qualified format. The format depends on the requirement suggested. Such as, your script log will have timestamp in a format like LOG_201505150732.log, but inside log, you timestamp might be set as 2015-05-15 07:32:03. Based on purpose, we use time in different ways.

Powershell does not require much more effort in playing with format. It is more straight forward than anything in Powershell. Simply, remember the table below to set the format :

SpecifierTypeExample Example Output
ddDay{0:dd}10
dddDay name{0:ddd}Tue
ddddFull day name{0:dddd}Tuesday
f, ff, …Second fractions{0:fff}932
gg, …Era{0:gg}A.D.
hh2 digit hour{0:hh}10
HH2 digit hour, 24hr format{0:HH}22
mmMinute 00-59{0:mm}38
MMMonth 01-12{0:MM}12
MMMMonth abbreviation{0:MMM}Dec
MMMMFull month name{0:MMMM}December
ssSeconds 00-59{0:ss}46
ttAM or PM{0:tt}PM
yyYear, 2 digits{0:yy}02
yyyyYear{0:yyyy}2002
zzTimezone offset, 2 digits{0:zz}-05
zzzFull timezone offset{0:zzz}-05:00
:Separator{0:hh:mm:ss}10:43:20
/Separator{0:dd/MM/yyyy}10/12/2002


Using toString() function, you can do all kinds of formatting you want.

For example, if you have to get the timestamp for a log file, use below :
$FILE_NAME="ABC_$($(get-date).toString("yyyyMMddhhmmss")).log"

If you want to output the time in log file, it must be little more readable. Such as below :
$MSG="$($(get-date).toString("yyyy/MM/dd HH:mm:ss" )) : Program Started"

There are lot many experiments possible with it. This is simple, yet effective way to handle time.
Enjoy scripting!!
 

Tuesday, May 5, 2015

#11 : PowerGUI : A great tool!

-- Still writing this article, I would come up with full details about PowerGUI. The tool is really interesting and I may also include a video on it.

Sorry for making you wait.. Please wait for sometime...

Monday, May 4, 2015

#65 : Error-Handling with Trap

In v1.0 of Windows Powershell, there was no Try-Catch-Finally feature. We had trap construct for the same purpose. I think, Trap was a new concept as it was not there in any of the existing .NET-based languages. But Powershell v1.0 somehow had this unusual feature. In most of the old machines, there will be Powershell v1.0 and we cannot use Try-Catch blocks for those servers. So if you are writing script for all versions of Windows, there is no option left except using Trap.

Let us see the Trap example below :



The above example will call two divide statement which will end up with divide-by-zero. There are two blocks where trap is declared :
1. At script level
2. At function level

You will notice that output will call Function level when it will fail inside function block and it will call script level trap when called outside function.

Hope this simple example will make you learn this correctly. Please send me your questions and suggestion if you have any. Learning from small example is always better if you want to understand something correctly.

That's it for today! Thanks for reading today and keep reading this blog which is updated everyday.


Sunday, May 3, 2015

Tool #4 : Powershell ISE with Powershell v4.0

Powershell ISE comes bundled with Powershell. The editor was useful in previous versions also, but version 4.0 comes with collapsing and expanding of functions and statement blocks. This is very important to have big functions collapsed as it avoids so much scrolling back and forth. Also, it makes script more readable if you are just reviewing someone's code. Syntax highlighting and Intellisense have already been there.

So, those who have not used it for some reasons. I would request them to give a try on this tool. If you do not see it in your newly installed Windows 2008 or 2012, you can try to add it from features.


Remarkable Features:

1. Intellisense feature
2. East of Debugging Code using Breakpoints
3. Collapsing and Expanding of blocks
4. Code and Output windows switching
5. Familiar shortcuts used in all Microsoft products such as F5 etc.

Below are some items which are missing in this version, hope Microsoft will add in future releases :
1. Script parameter passing is not possible.
2. There is no scope of writing GUI based tools.

If you find something interesting about this tool, please let me know.


 

Saturday, May 2, 2015

#64 : Backup Report Server Encryption Key

Report server encryption key is essential in recovering, migrating and troubleshooting. Although, we generally backup it when report server is built, but it is required to take backup time-to-time to avoid any miss-out. Scheduling a SQL Server job on the SQL Server will be sufficient and we can schedule it to run once a week.

Below is a simple Powershell script which can help you scheduling such a job :



You can schedule the job with Powershell subsystem or CMDExec subsystem depending on the standard followed in your organization.

Thanks for reading this article! Please do update me if you have issues running it.



Friday, May 1, 2015

#63 : Open Control Panel Items with Powershell

I don't see any purpose of opening control panel items. I expect you may need if you are something interactive which requires users to set something.

To open the Folder Options:
Show-ControlPanelItem -Name "Folder Options"


To open Internet Options: 
Show-ControlPanelItem -Name "Internet Options"


To open Firewall Settings:
Show-ControlPanelItem -Name "Windows Firewall"


There could be many such items in your control panel which differ from one computer to another. If you want to know the list of control panel items, use the below command :

Get-ControlPanelItem

This will take at least few seconds to get the results. You can play as much these controls.

I would suggest not to use the graphical controls if you are running any automated script which runs with scheduled task or SQL Server job. This may call the program in memory for so long. Such programs can be killed from Task manager or Powershell if started accidentally.

Hope you liked this article! We will see a new article tomorrow.
 

Thursday, April 30, 2015

#62 : Playing with Windows COM

This script is nothing more than just playing with Windows COM shell. I don't see any purpose of it. But this is good for playing, because as much you play, you learn a lot. If you cannot play with something, you will never understand things completely.





Hope you like this post, send your comments to me!
Enjoy!

Wednesday, April 29, 2015

#61 : How to connect SQL Server with Powershell?

Powershell can be used to run queries against SQL Server. In fact, what C# and other .NET Framework based languages can do, you can do all of them wit h Powershell. You can connect SQL Server and perform all operations which you do with Powershell.

Here is a simple code for this :


Hope you like this article! It's too late night (2:30 AM) and I have to go to bed.
Enjoy!

Sunday, April 26, 2015

#60 : Script to write into Excel Sheet

SUMMARY

In some cases, we need to create excel and upload as attachment to mail. This tasks is so simple when done manually, but we cannot be doing the same work everyday if we need to send Excel sheet everyday. We can try to automate it. But the automation should be as accurate as manual. It sounds very good, but sending a formatted excel document is not so easy.

We can simply attach a CSV which will automatically open in Excel, but CSV is not good for below reasons :

1. CSV does not show columns in correct length.
2. CSV does not color certain fields.
3. CSV will not show bold or italics.

So, the purpose will not be solved with CSV. So here I will use Microsoft ACE to generated the formatted report.

CODE




CONCLUSION

This article is still being written.
 

Saturday, April 25, 2015

#59 : Get Folder Size with Powershell

Sometimes, we need to check the folder size. Although, ls can give your results of certain files, but still you need to struggle to get the folder (directory) size. I wrote one small script to get this with Powershell. You may use this recipe if you are writing something where folder size is required to be checked.



Thanks for reading this article!

Thursday, April 23, 2015

#58 : Find the disk volumes in host

WMI gives a lot of such important information which makes windows administration more manageable. Scripting becomes more and more robust than ever before. 

Powershell can be used to call WMI objects and we can get so much information out of it. 

CODE : 
get-wmiobject win32_logicaldisk | select DeviceId,Size, FreeSpace



You might get a result in proper tabular format. There are lot many scripts possible with this. 
1. Script to report low disk space
2. Script to display disk inventory in multiple hosts 

If you have trouble writing scripts mentioned above, just add your request in comment,  I will pick from there.

Wednesday, April 22, 2015

#57 : Find running Services with Powershell

Find the List of Running Services:
You can get list of all Processes with command like Get-Service. This CmdLet gives you list of all services which are running and stopped.
But sometimes, you might need to know a list of Service which is currently running.
Below Statements can be used for the same -





#--Get the Names of Running Services --#  
Get-Service | where { $_.Status -eq "Running" } | format-table Name  




Stopping a Service with Powershell :

 


Stopping a service is fairly simple with Stop-Service command. Let's do it with a service named "Spooler".




#--Get the Names of Running Services --#  
Stop-Service "Spooler"  









Tuesday, April 21, 2015

#56 : Compression with Powershell or Creating zip file with Powershell

File compression is not at all straight forward in Powershell. Using Windows compression is error-prone. It gives unexpected results and fails silently. The problem is basically with file size larger than 3 Gigs. If file-size is larger than 3 Gigs, Windows 2003 based server will not complete the task and fail silently. If you have delivered it for any critical task, you will find yourself in a real trouble.

Windows native compression method:

Below is the code which can be used : 

#------------------------------------------------------------------------------------------
#     Script : compress_file.ps1
#     Author : Som DT.
#    Purpose : Compress file script
#------------------------------------------------------------------------------------------

function compress-file ([string]$file, [string]$zipfilename)
{
 echo "Compressing [$file] to [$zipfilename]."
 
 if(-not (test-path($zipfilename)))
 {
  set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
  (dir $zipfilename).IsReadOnly = $false
  
  $shellApplication = new-object -com shell.application
  $zipPackage = $shellApplication.NameSpace($zipfilename)
  
  $zipPackage.CopyHere($file)
 
  #--Add some delay to wait -# 
  do {
   $zipCount = $zipPackage.Items().count
   echo "Waiting for compression to complete ..."
   Start-sleep -Seconds 1
  }
  while ($zippackage.Items().count -lt 1)
 
  echo "Finished zipping successfully"
 
 }
} 

#------------------------------------------------------------------------------------------

#--Starting comressing the file --# 
compress-file "D:\new.txt" "D:\new.zip"

#------------------------------------------------------------------------------------------




This works fine with Windows 2008 and above operating system. But still there are two problems -

1. CopyHere function is a real mess. It does not stick to the point where this function is called. It moves ahead, so you need to put a logic to make the script wait till compression is over.
2. This is hard to predict if compression failed. Script might run infinite in some cases. This is genuine problem and above script is not recommended.

Monday, April 20, 2015

#55 : Process Handling with Powershell

You can get list of running Processes with command like Get-Process. 

Below command be used to get Names of all processes running - 


CODE: 
 

Stop a Process if the process is running :

I am not sure why somebody would need this. But anyways, just for learning - you can use below -
Below statement would stop each occurence of Notepad running.
CODE:
 

Find the Process which is using maximum CPU :

Yeah, this might be a good example.
CODE:
 

Find the Process which is using minumum CPU :

Below code is just one word different from above. Select-Object -First 1.
CODE:
Find the Process with more than one Occurences : 
CODE:

Sunday, April 19, 2015

#54 : How to upload file to SharePoint with Powershell?

Uploading to SharePoint is fairly simple with the below snippet. I am sharing the Gist script which might be useful for you. The only carefulness required here is to make sure that credentials are properly granted to the executing account.



Try above and let me know how it goes. Please update me in case of any issues.

Thanks for reading this article!

Saturday, April 18, 2015

#53 : Error Handling with $Error

$Error is an interesting array which records all error messages from current session. It can be cleared also and looked up for presence of any error message in last command. In most of the cases, you may want to set it clear and then look for $error[0].

Make sure when you check the $error.count right after you run the statement which you think as problematic statement.

Code:

$error.clear()

copy-item “c:\temp\abc.txt” “d:\abc.txt”

if ( $error.count -ne 0 )

{

echo “An error occurred in copy operation. Please review the message below:”

echo $error[0]

}

When you run the above in console and abc.txt does not exist, you will get an error message in red color and then from echo part as well. You might be thinking why we need this if error message is there in console. The reason behind using is that if you run the script from a scheduler and want output to be there in log file, this approach can help you a lot.

Other better methods of catching exceptions are:

Try.. Catch

Trap

We will discuss about them in next article. Test this approach and let know your responses.

Enjoy!

Friday, April 17, 2015

#52 : How to display fields of a Delimited file?

I think that delimited file might be a confusing term, but I simply mean with a file which has fields into it separated by a delimiter such as pipe(|) or tilde (~). In course of programming, you may see several such situations where you will have to read a CSV or something similar to that.

Okay, let's open Powershell command prompt and check the below code which will demonstrate you how to do it. Below is the piece of code which you can use :



With the above example, you can see that first field will be 0, second field will be 1 and so on.

Hope, you enjoyed reading!

Thursday, April 16, 2015

#51 : How to check if Port if open or not?

This is fairly simply to test if certain host is able to connect to a port or not with Telnet. Some of the new SQL Server installation do not have Telnet installed. In those cases, we can use Powershell to test is the port.


I will use System.Net.Sockets.TcpClient class to accomplish it. Below is the simple statement to get the Port status.

$tcp = New-Object System.Net.Sockets.TcpClient

$tcp.connect(“HOST1″ , 1234 )


The above results as blank where connection is successful, otherwise, you get an error message.


Thursday, April 2, 2015

#50 : How to check with Powershell that URL is responsive or not?

You can write script in Powershell to check the status of certain URL (Uniform Resource Locator). In some cases, we may need to monitor if certain intranet application is working or not. Sometimes SQL Server Reporting services are required to be checked if URL is responsive.



To use it, you may call the function like below :

Check-URL "http://yourapplicationname.com"


That’s it! You are done and nothing more is required.

Friday, March 27, 2015

#49 : Generating Random Numbers with Powershell


I never got a requirement where I need to generate a random number in Powershell. The reason is that I never develop something like game or script which runs on chance.  But there is one script which might need random number. The script will be all about generating complex passwords randomly. The script will generate a number between 1 and 26 to get a number and then a letter is generate from that number. The loop goes for as many characters you want in your random password. We will talk about the program in next post. For now, let's play with get-random cmdlet.

The cmdlet to be used is :Get-Random. Please review the syntax below. If syntax looks horrible, kindly take look in to examples, I bet you will not close this tab in your browser.

Syntax:

Get-Random [-InputObject] Object[] [-Count int] [-SetSeed int] [CommonParameters]



Example:

[1] Generate a number between 0 and 100.

Get-random -Minimum 0 -Maximum 100

- Run it multiple time and you will see a new number everytime.

[2] Generate a number within the list provided

get-random -input 8, 4, 12, 20, 24, 108 -count 1

Conclusion:

Get-Random cmdlet can be used for several purpose. At least, I know one purpose which is all about generating a random complex password. I will write the script and post very soon. The viewership of this blog has increased alot and people like and send their mails to me. I think, the time has come when I should write some well qualified scripts and publish in this blog, hope you all will like them.

Thanks!


Get-Random [-InputObject] Object[] [-Count int] [-SetSeed int] [CommonParameters]






Thursday, March 19, 2015

#48 : Speaking Script in Powershell

A script can be written which can talk to you and speak out - "Sir! Your copy job has completed." or something like "Sir! Please press any key to continue!". These all are not a fiction with Powershell and you don't have to write much more lines of code to accomplish. In fact, this is just a one liner!

(new-object -com SAPI.SpVoice).speak("One more Powershell tips")

So, I decided to write a completely talking script which will copy all file from one location to another.






One you run it, you would see Merlin talking ...




Once you run it, you will have more ideas about writing any interactive script which could give messages verbally. I am now thinking to write something which will take commands from microphone!!

Friday, March 6, 2015

#47 : Creating modules with Powershell

Powershell modules are extension to inbuilt cmdlets. You may download third-party modules or you can write them using C#. Along with some installation, modules are installed in Powershell.

List the modules available: 

Use get-module to list the modules.

Import an existing module: 

import-module <module_name>

Writing your own module with Powershell

You can write your own module in Powershell using below steps:
1. Create a file with below content: 

function do-nothing()
{
echo "You are in nothing"
}

function do-something( $i, $j)
{
echo "Result : $($i + $j)"
}

2. Save the file with .psm1 extension. I use test.psm1 as filename.

3. Import the module 

import-module c:\tst\test.psm1

4. Check if module is loaded

PS D:\Org\Powershell> Get-Module

ModuleType Name ExportedCommands
---------- ---- ----------------
Script test {do-something, do-nothing}


5. Run the command used 

PS D:\Org\Powershell> do-something 5 6
Result : 11


CONCLUSION

Overall, we have below advantages using this approach:
1. Increases code manageability
Any changes made in one module is copied over all the modules.

2. Increases code reusability :
You can use common tasks like sending mails or logging in one module and share in all the scripts.

3. Team work
If a team of people working, working in modules reduces burden on single person and everyone owns his own part.

Thursday, February 26, 2015

#46 : Get Cluster details with Powershell

Windows Cluster can be found in every enterprise. We want to have high availability of our server application which increases the scope of having clusters. We are talking about Windows clusters only, your requirement might not match if you are using third-party clusters by Veritas and others.

My requirement of getting cluster related information was different but it might suit any Windows administrator. Basically, I am DBA Engineer and I was writing script which could collect SQL Server cluster information. So it required to know if there are below resources available:

1. Network resource
2. Disk Resource
3. Nodes

PREREQUISITES

We are going to use cmdlets which are not available in Powershell as native. Yeah, you understood - we are going to import module. But I am not talking about any third party material (which I don't like). The module is provided by Microsoft itself. If you have Windows 2008 and above, you might find the module already. For Windows 2003 and previous versions, I will let you know different set of commands (I don't leave any stone unturned).

INITIAL STEPS

Step [1] Find if module is available
Please run below command to list all the modules.

get-module -listAvailable

Step [2] Import the Module

import-module failoverclusters

If you are writing any script, make sure you import the module.

ACTION 

1. Find the Network resource

Here, I will just tell you the cmdlet to know what all network resource names can be seen on Windows cluster.

Get-ClusterNetwork -Cluster <cluster name>

2. Find the Disk resource 

Get-ClusterResource -Cluster <Cluster name>

3. Cluster nodes info

Get-ClusterNode -Cluster <Cluster Name>

4. Find Cluster groups available

Get-ClusterGroup -Cluster <Cluster Name>

Below is the list of cmdlets which can help you manage cluster:

Add-ClusterDisk
Make a new disk available for use in a failover cluster. The disk (LUN) must be exposed to all nodes in the failover cluster, and should not be exposed to any other servers.

Add-ClusterFileServerRole
Create a clustered file server (resource group that includes one or more disks, on which you can create shared folders for users).

Add-ClusterGenericApplicationRole
Configure high availability for an application that was not originally designed to run in a failover cluster.

Add-ClusterGenericScriptRole
Configure an application controlled by a script that runs in Windows Script Host, within a failover cluster.

Add-ClusterGenericServiceRole
Configure high availability for a service that was not originally designed to run in a failover cluster.

Add-ClusterGroup
Add an empty resource group to the failover cluster configuration, in preparation for adding clustered resources to the group.

Add-ClusterNode
Add a node (server) to a failover cluster. Before adding the new node, you should run validation tests on the existing nodes together with the proposed new node.

Add-ClusterPrintServerRole
Create a clustered print server (a resource group that includes a printer and a disk for storing print job information and printer drivers).

Add-ClusterResource
Add a resource to a clustered service or application (resource group) in a failover cluster.

Add-ClusterResourceDependency
Add a resource to the list of resources that a particular resource depends on (using AND as the connector) within a failover cluster. Existing dependencies will remain in the list.

Add-ClusterResourceType
Add a resource type to a failover cluster, and specify information such as the dynamic-link library (DLL) to use with that resource type.

Add-ClusterServerRole
Add a group containing only a client access point and storage to the failover cluster configuration.

Add-ClusterSharedVolume
Make a volume available in Cluster Shared Volumes in a failover cluster.

Add-ClusterVirtualMachineRole
Create a clustered virtual machine, that is, a virtual machine that can be failed over if necessary to a different server in the failover cluster.

Block-ClusterAccess
Prevent the specified user or users from accessing a failover cluster.

Clear-ClusterDiskReservation
Clear the persistent reservation on a disk in a failover cluster.

Clear-ClusterNode
Clear the cluster configuration from a node that was evicted from a failover cluster.

Get-Cluster
Get information about one or more failover clusters in a given domain.

Get-ClusterAccess
Get information about permissions that control access to a failover cluster.

Get-ClusterAvailableDisk
Get information about the disks that can support failover clustering and are visible to all nodes, but are not yet part of the set of clustered disks.

Get-ClusterGroup
Get information about one or more clustered services or applications (resource groups) in a failover cluster.

Get-ClusterLog
Create a log file for all nodes (or a specific node) in a failover cluster.

Get-ClusterNetwork
Get information about one or more networks in a failover cluster.

Get-ClusterNetworkInterface
Get information about one or more network adapters in a failover cluster.

Get-ClusterNode
Get information about one or more nodes (servers) in a failover cluster.

Get-ClusterOwnerNode
For a resource in a failover cluster, get information about which nodes can own the resource. For a clustered service or application (a resource group), get information about the order of preference among owner nodes.

Get-ClusterParameter
Get detailed information about an object in a failover cluster, such as a cluster resource. This cmdlet is used to manage private properties for a cluster object.

Get-ClusterQuorum
Get information about the quorum configuration of a failover cluster.

Get-ClusterResource
Get information about one or more resources in a failover cluster.

Get-ClusterResourceDependency
Get information about the dependencies that have been configured between clustered resources in a failover cluster.

Get-ClusterResourceDependencyReport
Generate a report that lists the dependencies between resources in a failover cluster.

Get-ClusterResourceType
Get information about one or more resource types in a failover cluster.

Get-ClusterSharedVolume
Get information about Cluster Shared Volumes in a failover cluster.

Grant-ClusterAccess
Grant access to a failover cluster, either full access or read-only access.

Move-ClusterGroup
Move a clustered service or application (a resource group) from one node to another in a failover cluster.

Move-ClusterResource
Move a clustered resource from one clustered service or application to another within a failover cluster.

Move-ClusterSharedVolume
Move a Cluster Shared Volume to ownership by a different node in a failover cluster.

Move-ClusterVirtualMachineRole
Move the ownership of a clustered virtual machine to a different node.

New-Cluster
Create a new failover cluster. Before you can create a cluster, you must connect the hardware (servers, networks, and storage), and run the validation tests.

Remove-Cluster
Destroy an existing failover cluster. The affected servers will no longer function together as a cluster.

Remove-ClusterAccess
Remove a user from the access list on the cluster.

Remove-ClusterGroup
Remove a clustered service or application (also called a resource group) from a failover cluster.

Remove-ClusterNode
Remove a node from a failover cluster. After the node is removed, it no longer functions as part of the cluster unless you add it back to the cluster.

Remove-ClusterResource
Remove a clustered resource from the failover cluster.

Remove-ClusterResourceDependency
Remove a dependency between two resources in a clustered service or application within a failover cluster.

Remove-ClusterResourceType
Remove a resource type from a failover cluster.

Remove-ClusterSharedVolume
Remove a volume from the Cluster Shared Volumes in a failover cluster, and place it in Available Storage in the cluster.

Repair-ClusterSharedVolume
Run repair tools on a Cluster Shared Volume locally on a cluster node.

Resume-ClusterNode
Resume activity on a failover cluster node after you have suspended it (that is, paused it).

Resume-ClusterResource
Turn off maintenance for a disk resource or Cluster Shared Volume within a failover cluster.

Set-ClusterLog
Set the size and level of detail for the cluster log.

Set-ClusterOwnerNode
For a resource in a failover cluster, specify which nodes can own the resource. For a clustered service or application (a resource group), specify information about the order of preference among owner nodes.

Set-ClusterParameter
Control specific properties of an object in a failover cluster, such as a resource, a group, or a network.

Set-ClusterQuorum
Configure quorum options for a failover cluster.

Set-ClusterResourceDependency
Specify the resources that a particular resource depends on within a failover cluster. Existing dependencies will be overwritten by the dependencies that you specify.

Start-Cluster
Start the Cluster service on all nodes of the cluster on which it is not yet started.

Start-ClusterGroup
Bring one or more clustered services and applications (also known as resource groups) online on a failover cluster.

Start-ClusterNode
Start the Cluster service on a node in a failover cluster.

Start-ClusterResource
Bring a resource online in a failover cluster.

Stop-Cluster
Stop the Cluster service on all nodes in a failover cluster, which will stop all services and applications configured in the cluster.

Stop-ClusterGroup
Take one or more clustered services and applications (also known as resource groups) offline on a failover cluster.

Stop-ClusterNode
Stop the Cluster service on a node in a failover cluster.

Stop-ClusterResource
Take a resource offline in a failover cluster.

Suspend-ClusterNode
Suspend activity on a failover cluster node, that is, pause the node.

Suspend-ClusterResource
Turn on maintenance for a disk resource or Cluster Shared Volume so that you can run a disk maintenance tool without triggering failover.

Test-Cluster
Run validation tests for failover cluster hardware and settings. Tests can be run both before and after a cluster is set up.

Test-ClusterResourceFailure
Simulate a failure of a cluster resource.

Update-ClusterIPResource
Renew or release the DHCP lease for an IP address resource in a failover cluster.

Update-ClusterVirtualMachineConfiguration
Refresh the configuration of a clustered virtual machine within a failover cluster

Equivalent commands for pervious version of Windwos 2003: 

Cluster.exe <Cluster Name> /prop
Get-Cluster <Cluster Name> | fl *

Cluster.exe <Cluster Name> /priv
Get-Cluster <Cluster Name> | Get-ClusterParameter

Cluster.exe <Cluster Name> group
Get-ClusterGroup -Cluster <Cluster Name>

Cluster.exe <cluster Name> node
Get-ClusterNode -Cluster <Cluster Name>

Cluster.exe <cluster name> res
Get-ClusterResource -Cluster <Cluster name>

Cluster.exe <Cluster name> net
Get-ClusterNetwork -Cluster <cluster name>

Cluster.exe <cluster name> netint
Get-ClusterNetworkInterface -Cluster <cluster name>

Cluster.exe <cluster name> group /move:<Node name>
Move-ClusterGroup -Name <group name> -Node <Node name> -Cluster <cluster name>

Cluster.exe log
Get-ClusterLog

Cluster.exe <cluster name> /create …
New-Cluster

Cluster.exe <cluster name> group /add
Add-ClusterGroup

Cluster.exe <cluster name> group <group name> /on
Start-ClusterGroup -Name <group name> -Cluster <cluster name>

CONCLUSION
As you can see the module failoverclusters gives you more and more options to manage cluster. Sorry, I could not add any script for this article, but you may ask me in case you want, I will reply once I get time.

Wednesday, February 18, 2015

#45 : Display top n lines or last n lines of a file

Often we reach to a situation where we need to get top 10 or 100 lines of a file.
These commands are fairly simple in Unix shell programming and most of you must have used Head and Tail commands. Those commands work really fast and accurate.

Keeping these points in mind, I dig something and want to share will all of you.

How to use Head and Tail Commands in Powershell?

To get the top 10 lines -
Get-Content ".\file_test.txt" | select -First 10

To get the top 10 lines -

Get-Content ".\file_test.txt" | select -Last 10

Easy! This is power of Powershell !

Some more Examples:

Problem: Write a command to get 3rd line of a file.

Solution:
Get-Content ".\file_test.txt" | select -First 3 | select -Last 1

Problem: Write a command to skip 10 lines from top and display rest all lines of file.

Solution:
Get-Content ".\file_test.txt" | select -Skip 10

But this approach has one drawback, when file is so big, it takes a little more time to produce results.

To be able to read a big file, you can adjust Get-Content to read only few lines. As you saw, we were reading the complete file before that caused more memory consumption.



Enjoy Scripting!!

Thursday, February 12, 2015

#44 : Display Inputbox with Powershell

Hi All,

Powershell does not support InputBox itself. We might have to do some effort to achieve it. I did some research and found two methods can be used :

Below is the complete demonstration:



DEPLOYMENT STEPS

This method is extremely flexible and requires little more effort. If you COPY+PASTE, there is not much effort, but while developing I did some more effort.

Let's have look into the code.

I have created a function CustomInputBox which will create all the GUI interface and will return the user input.




function CustomInputBox([string] $title, [string] $message, [string] $defaultText) 
 {
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 

    $userForm = New-Object System.Windows.Forms.Form
    $userForm.Text = "$title"
    $userForm.Size = New-Object System.Drawing.Size(290,150)
    $userForm.StartPosition = "CenterScreen"
        $userForm.AutoSize = $False
        $userForm.MinimizeBox = $False
        $userForm.MaximizeBox = $False
        $userForm.SizeGripStyle= "Hide"
        $userForm.WindowState = "Normal"
        $userForm.FormBorderStyle="Fixed3D"
     
    $OKButton = New-Object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Size(115,80)
    $OKButton.Size = New-Object System.Drawing.Size(75,23)
    $OKButton.Text = "OK"
    $OKButton.Add_Click({$value=$objTextBox.Text;$userForm.Close()})
    $userForm.Controls.Add($OKButton)

    $CancelButton = New-Object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Size(195,80)
    $CancelButton.Size = New-Object System.Drawing.Size(75,23)
    $CancelButton.Text = "Cancel"
    $CancelButton.Add_Click({$userForm.Close()})
    $userForm.Controls.Add($CancelButton)

    $userLabel = New-Object System.Windows.Forms.Label
    $userLabel.Location = New-Object System.Drawing.Size(10,20)
    $userLabel.Size = New-Object System.Drawing.Size(280,20)
    $userLabel.Text = "$message"
    $userForm.Controls.Add($userLabel) 

    $objTextBox = New-Object System.Windows.Forms.TextBox
    $objTextBox.Location = New-Object System.Drawing.Size(10,40)
    $objTextBox.Size = New-Object System.Drawing.Size(260,20)
    $objTextBox.Text="$defaultText"
    $userForm.Controls.Add($objTextBox) 

    $userForm.Topmost = $True
    $userForm.Opacity = 0.91
        $userForm.ShowIcon = $False

    $userForm.Add_Shown({$userForm.Activate()})
    [void] $userForm.ShowDialog()

    $value=$objTextBox.Text 

    return $value

 }


$userInput = CustomInputBox "User Name" "Please enter your name." ""
 if ( $userInput -ne $null ) 
 {
  echo "Input was [$userInput]"
 }
 else
 {
  echo "User cancelled the form!"
}





CONCLUSION

You may try any of the merthod described above. I would suggest Method#2 is more flexible and you have much more scope to improve. But again, if users are used to have the same inputbox which was famous in previous years, Method#1 is for you.
Happy scripting !

#112: How to handle xml document in Powershell?

 In PowerShell, you can handle XML data using various cmdlets and methods provided by the .NET Framework. Here's a basic guide on how to...