Saturday, June 19, 2010

Some good links to Powershell

Good reading
http://www.techotopia.com/index.php/Using_COM_with_Windows_PowerShell

http://www.youdidwhatwithtsql.com/automating-internet-explorer-with-powershell/467
http://www.pvle.be/2009/06/web-ui-automationtest-using-powershell/
http://powershell.com/Mastering-PowerShell.pdf

Active Directory
http://blogs.technet.com/b/benp/archive/2007/04/10/creating-an-ad-shell.aspx
http://blogs.technet.com/b/benp/archive/2007/03/26/searching-the-active-directory-with-powershell.aspx

http://blogs.technet.com/b/benp/archive/2007/03/05/benp-s-basic-guide-to-managing-active-directory-objects-with-powershell.aspx

Good book to download
http://blogs.technet.com/b/chitpro-de/archive/2008/02/28/free-windows-powershell-workbook-server-administration.aspx

RAM Count : Poweshell

RAM in MB
$mem = Get-WmiObject -Class Win32_ComputerSystem
# Display memory
"This system has {0} MB Free Memory" -f $($mem.TotalPhysicalMemory/1mb)
Processor cOUNT
$system = Get-WmiObject -Class Win32_ComputerSystem

Non Working devices
Get-WmiObject Win32_PNPEntity | where {$_.ConfigManagerErrorcode -ne 0}

Friday, June 18, 2010

Determine whether a computer is a tower, a mini-tower, a laptop, and so on: Powershell

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colChassis = objWMIService.ExecQuery _
("Select * from Win32_SystemEnclosure")
For Each objChassis in colChassis
For Each objItem in objChassis.ChassisTypes
Wscript.Echo "Chassis Type: " & objItem
Next
Next

Right way to read a file in itration. Powershell

Foreach ($name in (Get-Content c:\names.txt))
{
# do something with $name
}

Service Pack in OS. Powershell

Get-WmiObject Win32_OperatingSystem |
Format-List BuildNumber,CSName,ServicePackMajorVersion

UPTIME of server in powershell

UPTIME
$myobj.uptime = (Get-Date) - [System.DateTime]::ParseExact($OSInfo.LastBootUpTime.Split(".")[0],'yyyyMMddHHmmss',$null)
$myobj.uptime = "$($myobj.uptime.Days) days, $($myobj.uptime.Hours) hours," +`
" $($myobj.uptime.Minutes) minutes, $($myobj.uptime.Seconds) seconds"

Adding data to database with Powershell

DaTA base: Add data
$ds = new-object System.Data.DataSet
$ds.Tables.Add("person")
[void]$ds.Tables["person"].Columns.Add("name",[string])
[void]$ds.Tables["person"].Columns.Add("last",[string])
$dr = $ds.Tables["person"].NewRow()
$dr["name"] = "ullas"
$dr["last"] = "t"
$ds.Tables["person"].Rows.Add($dr)
$dr

name last
---- ----
ullas t

Try Catch template for Powershell

Try Catch template
try
{
try
{
# Command that uses -erroraction stop or $erroractionpreference = 'Stop'
}
# Here we catch the Exception generated by the ErrorAction "Stop"
# Only necessary if there is any processing we want to do if the
# exception is of type ActionPreferenceStopExecution,
# otherwise this block can be deleted
catch [System.Management.Automation.ActionPreferenceStopException]
{
# Error Handling specific to ActionPreferenceStopException goes here
# Rethrow the "real" exception as a terminating error
Throw $_.exception
}
# All errors are caught and rethrown to the outer try/catch block
# as terminating errors to be handled.
catch
{
Throw $_.exception
}
}
# Here we can resume exception type handling as usual
catch #[System.Management.Automation.ItemNotFoundException]
{
"Got it!"
}

WMI Info on Excel

$strComputer = “.”

$Excel = New-Object -Com Excel.Application
$Excel.visible = $True
$Excel = $Excel.Workbooks.Add()

$Sheet = $Excel.WorkSheets.Item(1)
$Sheet.Cells.Item(1,1) = “Computer”
$Sheet.Cells.Item(1,2) = “Drive Letter”
$Sheet.Cells.Item(1,3) = “Description”
$Sheet.Cells.Item(1,4) = “FileSystem”
$Sheet.Cells.Item(1,5) = “Size in GB”
$Sheet.Cells.Item(1,6) = “Free Space in GB”

$WorkBook = $Sheet.UsedRange
$WorkBook.Interior.ColorIndex = 8
$WorkBook.Font.ColorIndex = 11
$WorkBook.Font.Bold = $True

$intRow = 2
$colItems = Get-wmiObject -class “Win32_LogicalDisk” -namespace “root\CIMV2? `
-computername $strComputer

foreach ($objItem in $colItems) {
$Sheet.Cells.Item($intRow,1) = $objItem.SystemName
$Sheet.Cells.Item($intRow,2) = $objItem.DeviceID
$Sheet.Cells.Item($intRow,3) = $objItem.Description
$Sheet.Cells.Item($intRow,4) = $objItem.FileSystem
$Sheet.Cells.Item($intRow,5) = $objItem.Size / 1GB
$Sheet.Cells.Item($intRow,6) = $objItem.FreeSpace / 1GB

$intRow = $intRow + 1

}
$WorkBook.EntireColumn.AutoFit()
Clear

Sunday, May 30, 2010

Sample of Powershell usage for displaying in IE

$oIE=new-object -com internetexplorer.application
$oIE.navigate2("About:blank")
while ($oIE.busy) {
    sleep -milliseconds 50
}
$oIE.visible=$true
$procList=ps |select-object ProcessName,Handles,NPM,PM,WS,VM,CPU,Id |convertto-html

$oDocBody=$oIE.document.documentelement.lastchild ;

#populate the document.body
$oDocBody.innerhtml=$procList 

$oDocBody.style.font="12pt Arial";
$oIE.document.bgcolor="#D7D7EA"

#Reading back from IE.
$oTBody=@($oIE.document.getElementsByTagName("TBODY"))[0] ;
foreach ($oRow in $oTBody.childNodes) 
{
   #check the 4 column(WS),and highlight it if it is greater than 5MB.
   $WS=(@($oRow.childNodes)[4].innerhtml) -as [int]  ;
   if (($ws -ne $null) -and ($WS -ge 5mb)) {
       $oRow.bgColor="#AAAAAA" ;
   }
}

#Prepare a title.

$oTitle=$oIE.document.createElement("P")
$oTitle.style.font="bold 20pt Arial"
$oTitle.innerhtml="Process List";
$oTitle.align="center" ;

#Display the title before the Table object.
$oTable=@($oIE.document.getElementsByTagName("TABLE"))[0] ;
$oDocBody.insertBefore($oTitle,$oTable) > $null;

A sample of IE automation with power shell

 
# Twitter login name or email
$username_or_email = "xxxxxxxxxxxxxxxx";
# Your twitter password
$password = "xxxxxxxxxxxx";
$url = "http://twitter.com/login";
 
# txt file containing 1 tweet per line
$tweets = Get-Content "$env:USERPROFILE\tweets.txt";
#Interval between tweets
$sleep = 60; 
 
# This is just an attempt to handle the situation where you are already logged into twitter
trap [Exception]
{
 # This will happen if you're already logged in
 if($_.Exception.Message -eq "Property 'value' cannot be found on this object; make sure it exists and is settable." -Or $_.Exception.Message -eq "You cannot call a method on a null-valued expression.")
 {
  # Try and skip this error
  continue;
 }
 else
 {
  # Fail for other Exceptions
  Write-Host -ForegroundColor Red $_.Exception.Message;
 }
}
 
# Create an ie com object
$ie = New-Object -com internetexplorer.application;
$ie.visible = $true;
$ie.navigate($url);
# Wait for the page to load
while ($ie.Busy -eq $true)
{
 Start-Sleep -Milliseconds 1000;
}
 
# Login to twitter
Write-Host -ForegroundColor Green "Attempting to login to Twitter.";
# Add login details
$ie.Document.getElementById("username_or_email").value = $username_or_email;
$ie.Document.getElementById("session[password]").value = $password;
# Click the submit button
$ie.Document.getElementById("signin_submit").Click();
# Wait for the page to load
while ($ie.Busy -eq $true)
{
 Start-Sleep -Milliseconds 1000;
}
 
# Loop through each tweet in the txt file
foreach($tweet in $tweets)
{
 $ie.Document.getElementById("status").value = $tweet;
 $ie.Document.getElementById("status_update_form").Submit();
 Write-Host -ForegroundColor Green "Tweeted; $tweet.";
 Start-Sleep -Seconds $sleep;
 # Check to see if ie is still busy and sleep if so
 while ($ie.Busy -eq $true)
 {
  Start-Sleep -Milliseconds 1000;
 }
}

Template for IE automation with PowerShell

<#
    .SYNOPSIS 
      Validates application login userid and password from a given excel sheet
    .EXAMPLE
     validateLogin users.xls
     This command picks userid and password from given excel sheets and validates from given URL
#>
#Set-PSDebug -trace 2 # Debug Information
#Set-PSDebug -step # Debug using stepping


if ($args) 
{
 throw "USAGE: validateLogin users.xls"
}

function openExcel($args)
{
 $xl = new-object -com Excel.Application
 foreach ( $wbk in $args )
 {
  foreach ($user in $users)
  {
   $xl.Workbooks.open($args) | out-null  #drop the object info output
   $xl.Cells.Item(1,1).Value()
   $xl.Cells.Item(3,3).Value()
   $xl.Cells.Item(6,8).Value()
   $xl.Workbooks.Close()
  }
 }
}


Function NavigateTo([string] $url, [int] $delayTime = 100)
{
  Write-Verbose "Navigating to $url"
  
  $global:ie.Navigate($url)
  
  WaitForPage $delayTime
}

Function WaitForPage([int] $delayTime = 100)
{
  $loaded = $false
  
  while ($loaded -eq $false) {
    [System.Threading.Thread]::Sleep($delayTime) 
    
    #If the browser is not busy, the page is loaded
    if (-not $global:ie.Busy)
    {
      $loaded = $true
    }
  }
  
  $global:doc = $global:ie.Document
}

Function SetElementValueByName($name, $value, [int] $position = 0) {
  if ($global:doc -eq $null) {
    Write-Error "Document is null"
    break
  }
  $elements = @($global:doc.getElementsByName($name))
  if ($elements.Count -ne 0) {
    $elements[$position].Value = $value
  }
  else {
    Write-Warning "Couldn't find any element with name ""$name"""
  }
}

Function ClickElementById($id)
{
  $element = $global:doc.getElementById($id)
  if ($element -ne $null) {
    $element.Click()
    WaitForPage
  }
  else {
    Write-Error "Couldn't find element with id ""$id"""
    break
  }
}

Function ClickElementByName($name, [int] $position = 0)
{
  if ($global:doc -eq $null) {
    Write-Error "Document is null"
    break
  }
  $elements = @($global:doc.getElementsByName($name))
  if ($elements.Count -ne 0) {
    $elements[$position].Click()
    WaitForPage
  }
  else {
    Write-Error "Couldn't find element with name ""$name"" at position ""$position"""
    break
  }
}

#Entry point
#$verbosePreference = "SilentlyContinue"
$verbosePreference = "Continue"

$global:ie = New-Object -com "InternetExplorer.Application"
$global:ie.Navigate("about:blank")
$global:ie.visible = $true
$global:ie.children



#NavigateTo "http://www.bing.com"
#SetElementValueByName "q" "powershell variable scope"
#ClickElementById "sb_form_go"
#Can also do: ClickElementByName "go"

#NavigateTo "http://mail.com"
Write-Host -ForegroundColor Green "Attempting to login to Web Application.";
#SetElementValueByName "login1" "xxx@yyy.com"
#SetElementValueByName "password" "password"
#SetElementValueByName "lr" "lang_en"
#ClickElementById "btnSignIn"

function validate
{
 begin{
  #All init for this function
 }

 process{
  #All process function
 }

 end{
  #All finilazers
 }
}

Saturday, May 29, 2010

Windows Macros with WSH

http://www.icpug.org.uk/national/features/030316fe.htm
Eg.
Dim Wsh
Set Wsh = Wscript.CreateObject("Wscript.Shell")
Wsh.AppActivate "Exploring"
Wsh.SendKeys "{F2}{END}{LEFT}{LEFT}{LEFT}{LEFT}{BS}{BS}{BS}~{DOWN}"

Name it macro.vbs

When I instantiate the WshShell object I need to be able to refer to it in some way. Wsh is a variable for this purpose so, first of all, I explicitly declare it with the Dim statement

Set Wsh = Wscript.CreateObject("Wscript.Shell")

This is where I make an instance of the WshShell object.

Note that, as I am using the CreateObject method of WScript, I use the dot notation Wscript.CreateObject to call the method. The bit in brackets is what is called the 'programmatic identifier' of the object to be created and its value is in the documentation! The created object is then assigned to wsh so I can refer to it.

Wsh.AppActivate "Exploring"

Having set everything up this is the first line of real coding. It uses the AppActivate method of the newly defined WshShell object to tell the computer which window is to be activated for subsequent operations. (Which window is given focus is the techie way of saying this!). The string value, "Exploring" in this example, says activate the windows whose title begins with 'Exploring'. On my version of Windows at least, that means a Windows Explorer window. Note that if two Windows Explorer windows were open this code may activate the wrong one. I have not found this to be a problem in the way I use the code as a keyboard macro, since the Explorer window I wish to use has focus already.

Wsh.SendKeys "{F2}{END}{LEFT}{LEFT}{LEFT}{LEFT}{BS}{BS}{BS}~{DOWN}"

This uses the SendKeys method of the created WshShell object to send the keys to the Explorer window. The bits in quotes are the keys to send. Standard alphanumeric keys are simply typed as is. Special code strings, usually in braces, are used to define function keys. The keys in the line above correspond with the keyboard process defined in the previous section. Here is a full list of code strings taken from the documentation for SendKeys. Note that there does NOT appear to be a way of sending the special keys on a Windows keyboard

keyboard.

Key
 Code String
 
BACKSPACE
 {BACKSPACE}, {BS}, or {BKSP}
 
BREAK
 {BREAK}
 
CAPS LOCK
 {CAPSLOCK}
 
DEL or DELETE
 {DELETE} or {DEL}
 
DOWN ARROW
 {DOWN}
 
END
 {END}
 
ENTER
 {ENTER} or ~
 
ESC
 {ESC}
 
HELP
 {HELP}
 
HOME
 {HOME}
 
INS or INSERT
 {INSERT} or {INS}
 
LEFT ARROW
 {LEFT}
 
NUM LOCK
 {NUMLOCK}
 
PAGE DOWN
 {PGDN}
 
PAGE UP
 {PGUP}
 
PRINT SCREEN
 {PRTSC}
 
RIGHT ARROW
 {RIGHT}
 
SCROLL LOCK
 {SCROLLLOCK}
 
TAB
 {TAB}
 
UP ARROW
 {UP}
 
F1
 {F1}
 
F2
 {F2}
 
F3
 {F3}
 
F4
 {F4}
 
F5
 {F5}
 
F6
 {F6}
 
F7
 {F7}
 
F8
 {F8}
 
F9
 {F9}
 
F10
 {F10}
 
F11
 {F11}
 
F12
 {F12}
 
F13
 {F13}
 
F14
 {F14}
 
F15
 {F15}
 
F16
 {F16}
 

The documentation also tells you how to send the Ctrl and Alt keys in combination with alphanumeric keys.

Having created the script with Notepad, or whatever, save it to a VBScript file, (a file which has a .vbs extension). For the purpose of this example I will assume it is saved to:

C:\My Documents\WindowsScripts\Remove(n).vbs

CONVERTING THE SCRIPT TO A KEYBOARD MACRO
You could run this script in the same way as the Hello.vbs script was run, but it would be pointless. If you double clicked the Remove(n).vbs file then it would be the file highlighted and the effect of the script would be to rename the file to Remove.vbs.

We need to highlight a file of choice to be renamed and then execute the script. The way to do this is to assign a key combination to run the script. For example, if we set things up so that the key combination Ctrl-Alt-z ran the script then we could highlight the file whose name is to be changed and then press Ctrl-Alt-z. As the script will, after execution, highlight the next file in the Explorer window we could amend the names of a group of adjacent files simply by pressing Ctrl-Alt-z as many times as necessary. Even if the odd file in the window does not need its name amending we could press cursor down instead of Ctrl-Alt-z and then carry on.


Windows provides a means of assigning a key combination to run a file. You have to create a shortcut to the file ON THE DESKTOP. Creating a shortcut is not sufficient. It has to be on the desktop! Create a shortcut anywhere else and the key combination does not work. Whoever dreamt up this restriction of Windows functionality was obviously on the sauce on the day in question! Nevertheless, it does mean I have finally found a use for the desktop. I never start a program by clicking a desktop icon. I'm a clean desktop man and do not like it overrun with icons!

In the example we want to create a shortcut to C:\My Documents\WindowsScripts\Remove(n).vbs on the desktop. Do this as follows:

Right click the desktop and select New and Shortcut from the context menu. 
Click the Browse button 
Navigate to the C:\My Documents\WindowsScripts directory 
Click the down arrow next to the 'Files of type' box and select All files 
In the list of files displayed select Remove(n).vbs and click the Open button 
Click the Next button 
Give the shortcut a name, say Remove(n), and click the Finish button. 
A shortcut with the name Remove(n) will appear on the desktop. Right click it and select Properties from the context menu. 
Put the cursor in the Shortcut key box by clicking the box 
Press Ctrl-Alt-z together 
Click the OK button. 
That is all there is to it. Any time you need the script to execute just press Ctrl-Alt-z.

CREATING OTHER KEYBOARD MACROS

Now that I have explained how to create this example keyboard macro you have the template to create others. You have two things to change in the script:

Replace the "Exploring" in the Wsh.AppActivate line with the start of the title of the windows in which the macro is to work.

Define the keys to send in the Wsh.SendKeys line.

Save the revised script as another file and create another shortcut on the desktop with a different key combination.

If you are only going to use the keyboard macros infrequently you may wish to create the desktop shortcut only at the time of use and always use the Ctrl-Alt-z combination for its Shortkey. It saves remembering lots of different combinations or choosing a combination which conflicts with a shortcut in the application being used.

CONCLUSION

I hope this discussion has opened your eyes as to the possibilities of Windows Scripting Host. I have already written my second script. I mentioned in the Blog at the beginning of the year a problem I was having at work, which I solved by an inelegant method of opening Explorer using Dynamic Data Exchange. It worked but, ever searching for the elegant method, I finally worked out a solution using a script, which did not use DDE at all. That script is now a fixture on my Office Shortcut Bar and my problem has gone away.

I am thinking of returning to another problem that has been with me since the beginning of Windows 9x. How to open 2 instances of Windows Explorer and tile them horizontally over the full screen. In this way I can drag and drop copy like was done with the old File Manager. At present I create this interface manually, when I need it. How much easier it would be if I could write a script to do the creation for me.

Update
Here is the script for dual Explorer windows:

'A script to open Dual Windows Explorers on folders of the user's choice.
'
'The script should be called with TWO parameter which define the folders to open
'
Dim sa
Set sa = Wscript.CreateObject ("Shell.Application")
If WScript.Arguments.Count = 2 Then
sa.explore WScript.Arguments.Item(0)
sa.explore WScript.Arguments.Item(1)
Else
WScript.Echo "Please call this script with TWO argument to define the folders to open"
End If
Wscript.sleep(1)
sa.TileHorizontally()


Maybe you have some problems that can be solved with a script. Now that you know about WSH, take a look at it and see if you can solve those problems and discover the joy of being in control of Windows.

If you create some useful scripts please send them to me for upload. They can then be shared with the whole ICPUG community.

READER WRITES

Cesar writes to say:

I just read your web page where you describe the use Windows scripting. I’m having looking for several days this type of solution. I was wondering if you could give me a tip. I need to create a simple script that basically executes the {scroll} + {scroll} combination, as simple as that. Is this something I can do with Windows scripting. I appreciate your page, it is going to be very useful for certain issues I need to solve.
I see no problems with sending what Cesar wants. The Help file for Windows Scripting 5.6 says the keys are: 

{SCROLLLOCK}{+}{SCROLLLOCK} 

(Note: There are 3 'L's in SCROLLLOCK!)

UPDATE: 25 APRIL 2004

One of the keys that the SENDKEYS method of WSH will not emulate is the Windows key (beside the ALT keys on a Windows keyboard). Also, it is not possible to define the Windows key as the keyboard trigger for a desktop shortcut.

Mike Newman writes to tell me of a program, Winkey, that will allow you to write Windows-key keyboard shortcuts. It is a free download at:

http://download.com.com/3000-2344-913626.html?tag=lst-0-1

Another problem with WSH is that it cannot emulate the numeric keypad keys. This makes it impossible to create, for example, the character defined by pressing the ALT key in combination with the numeric keypad keys 0230. Microsoft Word has an alternative shortcut to this character, press CTRL-& followed by a, but this will not apply to all applications. Why would generation of this character be useful? Apparently, Esperanto writers use this and other symbols to write certain Esperanto characters that are not available in English. If anyone has a solution to this puzzle let me know.

Friday, May 28, 2010

Selenium Testing articles

1) http://blogs.atlassian.com/developer/2009/06/selenium_testing_with_windows.html

2) http://www.thoughtworks-studios.com/twist-agile-test-automation/1.0/help/how_do_i_use_selenium_to_test_https_sites.html

3) http://yuce.tekol.net/2009/10/web-application-testing-with-selenium.html

Wednesday, May 26, 2010

Application Status Checking with WLST

def appStatus(server_name):
       try:
           print '---------------------- Application status---------------------'
           mBeans=adminHome.getMBeansByType("ApplicationRuntime")
           for bean in mBeans:
               if server_name != bean.getObjectName().getLocation():
                   continue
               components= bean.lookupComponents()
               for componentRTList in components:
                   #ejbRTList=componentRTList.getMBeansByType("EJBComponentRuntime")
                   app = componentRTList.getParent().getName()
                   istate=componentRTList.getDeploymentState()
                   if istate == 0:
                       istate='UNPREPARED'
                   if istate == 1:
                       istate='PREPARED'
                   if istate == 2:
                       istate='ACTIVE'
                   if istate == 3:
                       istate='NEW'

                   print "%65s %65s %7s" % (str(componentRTList.getName()), app, istate)

       except:
           print "This Server has no Applications"

Saturday, May 08, 2010

Perl: Reading Processes from Unix

Here is a way using pipes

open(PS_F, "ps -f|");

while () {
($uid,$pid,$ppid,$restOfLine) = split;
# do whatever I want with the variables here ...
}

close(PS_F);

You can also try with split(/\s+/,$_)

Good Presentation on Patterns

http://www.cs.clemson.edu/~malloy/courses/patterns/slides/

Friday, May 07, 2010

Perl and Unix Processes control

Here is a script fot this

http://aplawrence.com/Unix/perlforkexec.html

http://docstore.mik.ua/orelly/perl/cookbook/index.htm

Wednesday, April 28, 2010

Itrating Hashes in Perl: Many ways

1) If you just want the keys and do not plan to ever read any of the values, use keys():

foreach my $key (keys %hash) { ... }

2) If you just want the values, use values():

foreach my $val (values %hash) { ... }

3) If you need the keys and the values, use each():

keys %hash; # reset the internal iterator so a prior each() doesn't affect the loop
while(my($k, $v) = each %hash) { ... }

4) If you plan to change the keys of the hash in any way except for deleting the current key during the iteration, then you must not use each(). For example, this code to create a new set of uppercase keys with doubled values works fine using keys():

%h = (a => 1, b => 2);

foreach my $k (keys %h)
{
$h{uc $k} = $h{$k} * 2;
}

Command line options with Perl: EG

#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Std;
use vars qw/ %opts /;

getopts('he:c:', \%opts );
usage() if $opts{h};
usage() if($opts{e} eq "" or $opts{c} eq "");

sub usage(){
print "This program should be used as below\n";
print "usage: $0 [-h] [e petrol] [-c elgi]\n";
print " -h : this (help) message\n";
print " -e : energy name\n";
print " -c : compressor name\n";
print " example: $0 -e petrol -c elgi\n";
exit;
}

Sunday, April 25, 2010

Tips and Tricks in Perl

Create an array from a string
@months = split ' ', "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
or
@months = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/

Create a string from an array.
@stuff = ("hello", 0..9, "world"); $string = join '-', @stuff

Generate an array with even numbers from 1 to 100
perl -le '@even = grep {$_ % 2 == 0} 1..100; print "@even"'

The spaceship operator <=>
my @numbers = (-59, 99, 87, 1900, 42, 1, -999, 30000, 0);
my @sorted = sort { $a <=> $b } @numbers;
print "@sorted\n";
# output: -999 -59 0 1 42 87 99 1900 30000

Saturday, April 24, 2010

Random password generator in perl

Here is a oneliner for this

perl -le 'print map { ("a".."z")[rand 26] } 1..8'

Here the map function executes ("a".."z")[rand 26] code 8 times (because it iterates over the dummy range 1..8). In each iteration the code chooses a random letter from the alphabet. When map is done iterating, it returns the generated list of characters and print function prints it out by concatenating all the characters together.

If you also wish to include numbers in the password, add 0..9 to the list of characters to choose from and change 26 to 36 as there are 36 different characters to choose from:

perl -le 'print map { ("a".."z", 0..9)[rand 36] } 1..8'

If you need a longer password, change 1..8 to 1..20 to generate a 20 character long password

From http://www.catonmat.net/blog/perl-one-liners-explained-part-four/

Friday, April 23, 2010

Getopts::Long HowTo in Perl

Here is an excellent link

http://www.devshed.com/c/a/Perl/Using-GetoptLong-More-Command-Line-Options-in-Perl/

Thursday, April 22, 2010

Callback function in Perl: EG

#!/usr/bin/perl
#use strict;
#use warnings;

my $adder = sub {
my ( $arg1, $arg2 ) = @_;
return $arg1 + $arg2;
};

my $multiplier = sub {
my ( $arg1, $arg2 ) = @_;
return $arg1 * $arg2;
};

sub doit {
my ($action, $arg1, $arg2) = @_;
return $action->( $arg1, $arg2 );
}

# This returns 30
my $val1 = doit( $adder, 10, 20 );

# This returns 200
my $val2 = doit( $multiplier, 10, 20 );

Automatically include many file from many directory

In case you write a perl program to include a require with lot of file here is a small program for that.

#!/usr/bin/perl
use strict;
use warnings;
&putAllIncludeFiles;
sub putAllIncludeFiles{
        my @thefiles=readAllFilesFromDirectories("/home/tullas/lesson/framework/lib","/home/tullas/lesson/framework/conf");
        my $f;
        foreach $f (@thefiles){
                require $f;
        }
}
sub readAllFilesFromDirectories{
   my $filename;
   my @filenames;
   foreach (@_) {
        opendir ( DIR, $_ ) || die "Error in opening dir $_\n";
        while( ($filename = readdir(DIR))){
                unless ( ($filename eq ".") || ($filename eq "..") ){
                        #print("$filename\n");
                        push @filenames,$_ . "/" . $filename;
                        $filename = "";
                }
        }
   }
   return @filenames;
   closedir(DIR);
}

Wednesday, April 21, 2010

Parallel execution of command in BASH

This script can be used for parallel execution of any command or shell script for faster execution of that command. Say you have a program called prog which process some jpg files. Then you do

parallel -j 3 prog *.jpg

Here 3 prog program will run simultanously
or
parallel -j 3 "prog -r -A=40" *.jpg
to pass args to prog.

Furthermore, -r allows even more sophisticated commands by replacing asterisks in the command string by the argument:
parallel -j 6 -r "convert -scale 50% * small/small_*" *.jpg
I.e. this executes convert -scale 50% file1.jpg small/small_file1.jpg for all the jpg files. This is a real-life example for scaling down images by 50% (requires imagemagick).
Finally, here’s the script. It can be easily manipulated to handle different jobs, too. Just write your command between #DEFINE COMMAND and #DEFINE COMMAND END.

Here is the parallel program
#!/bin/bash
NUM=0
QUEUE=""
MAX_NPROC=2 # default
REPLACE_CMD=0 # no replacement by default
USAGE="A simple wrapper for running processes in parallel.
Usage: `basename $0` [-h] [-r] [-j nb_jobs] command arg_list
  -h  Shows this help
 -r  Replace asterix * in the command string with argument
 -j nb_jobs  Set number of simultanious jobs [2]
 Examples:
  `basename $0` somecommand arg1 arg2 arg3
  `basename $0` -j 3 \"somecommand -r -p\" arg1 arg2 arg3
  `basename $0` -j 6 -r \"convert -scale 50% * small/small_*\" *.jpg"

function queue {
 QUEUE="$QUEUE $1"
 NUM=$(($NUM+1))
}

function regeneratequeue {
 OLDREQUEUE=$QUEUE
 QUEUE=""
 NUM=0
 for PID in $OLDREQUEUE
 do
  if [ -d /proc/$PID  ] ; then
   QUEUE="$QUEUE $PID"
   NUM=$(($NUM+1))
  fi
 done
}

function checkqueue {
 OLDCHQUEUE=$QUEUE
 for PID in $OLDCHQUEUE
 do
  if [ ! -d /proc/$PID ] ; then
   regeneratequeue # at least one PID has finished
   break
  fi
 done
}

# parse command line
if [ $# -eq 0 ]; then #  must be at least one arg
 echo "$USAGE" >&2
 exit 1
fi

while getopts j:rh OPT; do # "j:" waits for an argument "h" doesnt
    case $OPT in
 h) echo "$USAGE"
  exit 0 ;;
 j) MAX_NPROC=$OPTARG ;;
 r) REPLACE_CMD=1 ;;
 \?) # getopts issues an error message
  echo "$USAGE" >&2
  exit 1 ;;
    esac
done

# Main program
echo Using $MAX_NPROC parallel threads
shift `expr $OPTIND - 1` # shift input args, ignore processed args
COMMAND=$1
shift

for INS in $* # for the rest of the arguments
do
 # DEFINE COMMAND
 if [ $REPLACE_CMD -eq 1 ]; then
  CMD=${COMMAND//"*"/$INS}
 else
  CMD="$COMMAND $INS" #append args
 fi
 echo "Running $CMD" 

 $CMD &

 #Change:
 #$CMD &

 #To:
 #eval “$CMD &”

 #If you want to do things like:
 #par.sh ‘tr -d ” ” * > $(basename * .txt)-stripped.txt’ *.txt

 #Without the eval it’ll treat > and $(basename…) as arguments to tr.


 # DEFINE COMMAND END

 PID=$!
 queue $PID

 while [ $NUM -ge $MAX_NPROC ]; do
  checkqueue
  sleep 0.4
 done
done
wait # wait for all processes to finish before exit

Source is at 
http://pebblesinthesand.wordpress.com/2008/05/22/a-srcipt-for-running-processes-in-parallel-in-bash/

Tuesday, April 06, 2010

ETL4ALL look like a good bet for small companies

Here is a link to ETL4ALL company website.

http://www.ikan.be/

Converting XML with XSLT and Java

Here is the code in Java to do this. No external library is needed.


import java.io.*;

/**
* A simple demo of JAXP 1.1
*/
public class SimpleJaxp {

/**
* Accept two command line arguments: the name of
* an XML file, and the name of an XSLT stylesheet.
* The result of the transformation
* is written to stdout.
*/
public static void main(String[] args)
throws javax.xml.transform.TransformerException {
if (args.length != 2) {
System.err.println("Usage:");
System.err.println(" java " + SimpleJaxp.class.getName( )
+ " xmlFileName xsltFileName");
System.exit(1);
}

File xmlFile = new File(args[0]);
File xsltFile = new File(args[1]);

javax.xml.transform.Source xmlSource =
new javax.xml.transform.stream.StreamSource(xmlFile);
javax.xml.transform.Source xsltSource =
new javax.xml.transform.stream.StreamSource(xsltFile);
javax.xml.transform.Result result =
new javax.xml.transform.stream.StreamResult(System.out);

// create an instance of TransformerFactory
javax.xml.transform.TransformerFactory transFact =
javax.xml.transform.TransformerFactory.newInstance( );

javax.xml.transform.Transformer trans =
transFact.newTransformer(xsltSource);

trans.transform(xmlSource, result);
}
}

Sunday, April 04, 2010

XML Command tool for UNIX

Here is a tool which can help automation of XML file from UNIX

http://xmlstar.sourceforge.net/

Wednesday, March 31, 2010

File to Hash Technique: Multiple values

If you have a file like below
#File test.txt
usa, phili
usa, cali
france, paris
france, marcille
india, delhi
usa, atlanta

Script to do that is below.

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my %table = ();

open(FILE, "test.txt") or die("Unable to open manifest due to $!");
while ()
{
chomp;
my ($key, $val) = split /, /;
$table{$key} .= exists $table{$key} ? ",$val" : "$val";
}
close(FILE);
print Dumper(\%table);


Here is the output.

$VAR1 = {
'usa' => ',phili,cali,atlanta',
'france' => ',paris,marcille',
'india' => ',delhi'
};

Perl Reference

Say you have a file like this.

Chicago, USA
Frankfurt, Germany
Berlin, Germany
Washington, USA
Helsinki, Finland
New York, USA

We need an output like below.

Finland: Helsinki.
Germany: Berlin, Frankfurt.
USA: Chicago, New York, Washington.

To do this it would be good to use perl references as below

my %table;
while (<>) {
chomp;
my ($city, $country) = split /, /;
$table{$country} = [] unless exists $table{$country};
push @{$table{$country}}, $city;
}
foreach $country (sort keys %table) {
print "$country: ";
my @cities = @{$table{$country}};
print join ', ', sort @cities;
print ".\n";
}

More explanation on references is here http://perldoc.perl.org/perlreftut.html

Monday, March 29, 2010

WMI Script to Terminate a Process on a Distant Machine

Option Explicit
Dim objWMIService, objProcess, colProcess
Dim strComputer, strProcessKill, strInput
strProcessKill = "'calc.exe'"

' Input Box to get name of machine to run the process
Do
strComputer = (InputBox(" ComputerName to Run Script",_
"Computer Name"))
If strComputer <> "" Then
strInput = True
End if
Loop until strInput = True


Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")

Set colProcess = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = " & strProcessKill )
For Each objProcess in colProcess
objProcess.Terminate()
Next
WSCript.Echo "Just killed process " & strProcessKill _
& " on " & strComputer
WScript.Quit

Start Process on a Remote Machine

Option Explicit
Dim objWMIService, objProcess
Dim strShell, objProgram, strComputer, strExe, strInput
strExe = "Calc.exe"
' Input Box to get name of machine to run the process
Do
strComputer = (InputBox(" ComputerName to Run Script",_
"Computer Name"))
If strComputer <> "" Then
strInput = True
End if
Loop until strInput = True

' Connect to WMI
set objWMIService = getobject("winmgmts://"_
& strComputer & "/root/cimv2")
' Obtain the Win32_Process class of object.
Set objProcess = objWMIService.Get("Win32_Process")
Set objProgram = objProcess.Methods_( _
"Create").InParameters.SpawnInstance_
objProgram.CommandLine = strExe

'Execute the program now at the command line.
Set strShell = objWMIService.ExecMethod( _
"Win32_Process", "Create", objProgram)

WScript.echo "Created: " & strExe & " on " & strComputer
WSCript.Quit

Categories of VBScript 800xxxxx error codes

Code 80005xxx - ADSI errors
Code 8007xxxx - Operating System error e.g. Windows 2003 / XP
Code 800Axxxx - Syntax errors
Sundry Errors


Code 80005xxx - ADSI errors
Errors beginning with 80005xxx point to an ADSI error in your VBScript. While the message box calls them ADSI, I think of them as LDAP errors. For example, suppose that you are scripting a user's properties and you type givename instead of givenName (two ns), that mistake in the ADSI / LDAP name would generate an 80005xxx error.

Code 80005000 Object Required
Code 80005001 An unknown ADSI domain object was requested
Code 80005002 An unknown ADSI user object was requested
Code 80005003 An unknown ADSI computer object was requested
Code 8000500D The directory property cannot be found


Sundry Errors - Including WMI and MSN
Code 8002009 Error Setting Default Printer
Code 80020005 Type mismatch
Code 8002801c DllRegisterServer in COM failed
Code 800401E4 Syntax error
Code 80040E14 One or more errors occurred during processing of command
Code 80040E37 Table does not exist
Code 80041001 Call Failed
Code 80041002 Object not Found
Code 80041006 Insufficient Memory
Code 80041010 Spelling mistake in a keyword
Code 80041013 Provider not Found
Code 80041014 Component Error
Code 80041021 Syntax error in WMI winmgmts \\
Code 80048820 MSN Messenger server problem
Code 80048821 MSN Messenger email username problem
Code 80048823 MSN Messenger password
Code 8004888D MSN Service is temporarily unavailable
Code 81000306 MSN Messenger server down?
Code 81000314 MSN Messenger server down?


Code 8007xxxx - Operating System error e.g. Windows 2003 / XP
If your error begins with 8007xxxx then look for an factor outside VBScript. For instance, check the spelling of the name of your share or printer. Another possibility is that the server named in the script, is simply down or otherwise unavailable.

Code 80070005 Access denied
Code 80070035 The network PATH cannot be found
Code 80070043 The network NAME cannot be found
Code 80070055 The local device name is already in use
Code 8007007B The filename, directory or volume is incorrect
Code 800704B0 The specified device name is invalid
Code 800704B2 An attempt was made to remember a device .......
Code 800704B3 No network provider accepted the given network path
Code 800704CA This network connection does not exist
Code 800704C3 Multiple Connections to a server or shared resource...
Code 800704CF The network location cannot be reached
Code 8007052E Logon Failure: unknown user name or bad password
Code 80070571 The media is corrupt
Code 800706B5 The Interface is Unknown
Code 800706BA The RPC server is unavailable
Code 80070709 The Printer name is invalid
Code 80070961 This network connection has files open or requests pending
Code 80071329 Object Already Exists
Code 8007200E The Directory Service is Busy
Code 80072020 An operations error occurred
Code 8007202B A referral was returned from the server
Code 80072030 There is no such object on the server
Code 80072032 LDAP syntax error. Possibly a missing element e.g. cn=
Code 80072035 The server is unwilling to process the request
Code 8007203A The server is not operational
Code 80072EE2 Windows Update Service Problem


Code 8009xxxx
Code 80092023 Illegal character in a key name for a certificate

Code 800Axxxx Syntax errors
In VBScript, there are 53 syntax errors all beginning with 800Axxxx. These errors should be among the easiest to cure because the message often includes the missing punctuation mark or bracket.

Code 800A0005 Invalid Procedure Call
Code 800A000D Type Mismatch
Code 800A0035 File not found
Code 800A003A File Already Exists
Code 800A0046 Permission denied
Code 800A004C Path not found
Code 800A01A8 Object required
Code 800A01AD ActiveX component can't create object
Code 800A01B6 Object doesn't support this property or method
Code 800A01BD Object doesn't support this ACTION
Code 800A01C3 Object not a collection
Code 800A01C2 Invalid property assignment
Code 800A01CE Remote Server does not exist (or is unavailable)
Code 800A01F4 Variable undefined
Code 800A01F5 Illegal assignment
Code 800A03EA Syntax Error
Code 800A03EE Expected ')'
Code 800A03F1 Variable is undefined
Code 800A03F2 Expected Identifier
Code 800A03F4 Variable Undefined
Code 800A03F6 Expected End
Code 800A03FD Expected 'Case'
Code 800A0400 Expected statement
Code 800A0401 Expected end of statement
Code 800A0407 Invalid Number
Code 800A0408 Invalid Character
Code 800A0409 Unterminated string constant
Code 800A041F Unexpected Next
Code 800A139B - Expected ']' in regular expression
Code 800A139A - Expected quantifier in regular expression
Code 800A0CC1 Item cannot be found in the collection

Who is Logged in now in windows

Here is a WMI script to find out who is logged into the system at the moment.

#whoIsLogged.vbs

Dim objWMIService, objComputer, colComputer
Dim strLogonUser, strLogonUser1, strComputer

strComputer = "."
strComputer = InputBox("Enter Computer name", _
"Find Logon User", strComputer)
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colComputer = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")

For Each objComputer in colComputer
If not objComputer.UserName = "" Then
strLogonUser = Split(objComputer.UserName,"\")
strLogonUser(1) = UCase(Left(strLogonUser(1),1))_
& Trim(Mid(strLogonUser(1),2,20))
Wscript.Echo strLogonUser(1) & " is logged on at " _
& strComputer
Else
Wscript.Echo "No one is currently logged on at " _
& strComputer
End If
Next

Automating FTP in windows

Here is a way to automate file upload using FTP in windows. Make a bat file called fileup.bat

@echo off
echo user MyUserName> ftpcmd.dat
echo MyPassword>> ftpcmd.dat
echo bin>> ftpcmd.dat
echo put %1>> ftpcmd.dat
echo quit>> ftpcmd.dat
ftp -n -s:ftpcmd.dat SERVERNAME.COM
del ftpcmd.dat

You can now run this using below command

fileup FileToUpload.zip

Saturday, March 20, 2010

Bash commands from Java: Good way

A string can be executed in the standard java way:
def command = """ping -c1 -W1 hostname""" // Create the String
def proc = command.execute() // Call *execute* on the string
proc.waitFor() // Wait for the command to finish

// Obtain status and output
println "return code: ${ proc.exitValue()}"
println "stderr: ${proc.err.text}"
println "stdout: ${proc.in.text}" // *out* from the external program is *in* for groovy

Thursday, March 04, 2010

Cython

Use this in case you want to create dll i n windows or .so files in UNIX. Its based on Python.

http://cython.org/

Thursday, February 04, 2010

Extracting Left side of Coma Sperated String

Here is the formula with eg

A1 = Ullas,Thachudayakaimal

=LEFT(A1,FIND(",",A1,1)-1)

The result is

Ullas

Wednesday, January 27, 2010

Flat file to XML Conversion

If you need to convert flat file to XML look no further. Here is the Java software that can be used for this.

http://servingxml.sourceforge.net/