Showing posts with label automate. Show all posts
Showing posts with label automate. Show all posts

Thursday, November 22, 2007

Two PowerShell articles on MSDN magazine


December07Coverlg

In this month's issue of the MSDN Magazine, there are two articles on PowerShell.

Ever wanted to perform automation on windows forms or click a button in a window, etc?

Dr. James McCaffrey (blog link) shows how to create a small collection of custom Windows PowerShell cmdlets (eight custom cmdlets) that perform Windows UI automation tasks.

The sample cmdlets includes: get-window, get-control, get-controlByIndex, send-chars, send-click, get-listBox, send-menu, and get-textBox.

 

The second article "Extend Windows PowerShell With Custom Commands" by Jim Truher discusses:

  • Windows PowerShell SDK
  • Using the System.IO.IsolatedStorage namespace
  • Overriding default cmdlet behavior
  • Installing and using custom cmdlets

You can also download the magazine in HTML Help (.chm) format here. Click the month link and try to download the file in your language. BTW, the English version for December 2007 (EN) is broken :-(

Thursday, September 13, 2007

FTP transfers automation

 

Sapien technologies just released a com DLL to support simple FTP transfers. It supports the get/put FTP verbs, and I already tested them successfully. Its free to use and can be downloaded from Sapien's website. Thanks Sapien!

The download file includes two VBScripts files, one for upload and one for downloads. Here's a simple conversion to PowerShell.

 

Before starting using the functions, read the readme file, copy the DLL to system32 directory and register it:

regsvr32.exe ftp.dll

 

Cool, lets start

 

###############3

 

function Get-FTPFile{
    param(
        [string]$url,
        [string]$port=21,
        [string]$user,
        [string]$pass,
        [string]$RemoteFilePath,
        [string]$localPath
    )

    $ftp = new-object -com Primalscript.FTPTransfer;
    $ftp.Passive = 1;
    $ftp.port = $port;

    if($ftp.Connect($url,$user,$pass) -eq 0){
        "Can't connect. " + $ftp.Status;
    } else {
        "Starting download"
        If($ftp.Get($RemoteFilePath,$localPath) -eq 0){
            "Error downloading file " + $ftp.Status;
        } Else {
            "Download complete";
        }
        $ftp.Disconnect();
    }
}

 

Usage:

Get-FTPFile <ftpUrl> <port> <username> <password> <RemoteFilePath> <localDonloadPath>

 

############################

 

function Put-FTPFile{
    param(
        [string]$url,
        [string]$port=21,
        [string]$user,
        [string]$pass,
        [string]$localFile,
        [string]$RemotePath
    )

    $ftp = new-object -com Primalscript.FTPTransfer;
    $ftp.Passive = 1;
    $ftp.port = $port;

    if($ftp.Connect($url,$user,$pass) -eq 0){
        "Can't connect. " + $ftp.Status;
    } else {
        if($ftp.Put($RemotePath,$localFile) -eq 1){
            "success upload";           
        } else {
            "Error uploading file. " +$ftp.Status;
        }
        $ftp.Disconnect();
    }
}

 

Usage:

Get-FTPFile <ftpUrl> <port> <username> <password> <localUploadFile> <RemoteUploadPath>

 ##############

 

I'm maybe missing something, but I noticed when using the Put-FTPFile that even if the upload was successful, Put() returns 1 (error???) instead of 0. I commented about it in Spain's website FTP tool page.

 

UPDATE 09/19/2007:

Here's Don Jones reply:

0 is bad, 1 is good news.

1 = success (C++ TRUE)
0 = failure (C++ FALSE)

 

After all, I did miss something :-)

Thanks Don.

Friday, August 31, 2007

Query HTTP status codes and headers with PowerShell


I wrote this after a posting it in the PowerShell newsgroup. Three methods to the task:


1. Xml Http (com object)

$url = "http://www.cnn.com"
$xHTTP = new-object -com msxml2.xmlhttp;
$xHTTP.open("GET",$url,$false);
$xHTTP.send();
$xHTTP.ResponseText; # returns the html doc like downloadstring
$xHTTP.status # returns the status code

 

PS C:\Scripts> $xHTTP.getAllResponseHeaders()
Date: Fri, 31 Aug 2007 19:05:39 GMT
Server: Apache
Accept-Ranges: bytes
Cache-Control: max-age=60, private
Expires: Fri, 31 Aug 2007 19:06:31 GMT
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 30296
Content-Type: text/html
Keep-Alive: timeout=5, max=64
Connection: Keep-Alive

PS C:\Scripts> $xHTTP.getResponseHeader("Content-Length")
30296
PS C:\Scripts> $xHTTP.status
200
PS C:\Scripts> $xHTTP.statusText
OK

# $xHTTP.responseText will return the document text.

 

 

2. System.Net.HttpWebRequest

$url = "http://www.cnn.com"
$req=[system.Net.HttpWebRequest]::Create($url);
$res = $req.getresponse();
$stat = $res.statuscode;
$res.Close();

 

PS C:\Scripts> $res

IsMutuallyAuthenticated : False
Cookies : {}
Headers : {Vary, X-Pad, Keep-Alive, Connection...}
ContentLength : 135531
ContentEncoding :
ContentType : text/html
CharacterSet : ISO-8859-1
Server : Apache
LastModified : 8/31/2007 7:01:46 PM
StatusCode : OK
StatusDescription : OK
ProtocolVersion : 1.1
ResponseUri : http://www.cnn.com/
Method : GET
IsFromCache : False
PS C:\Scripts> $res.Headers
Vary
X-Pad
Keep-Alive
Connection
Accept-Ranges
Content-Length
Cache-Control
Content-Type
Date
Expires
Server

PS C:\Scripts> $res.GetResponseHeader("Content-Length")
135531

-or-  $res.<HeaderString>

$res.ContentLength
135531

PS C:\Scripts> $res.StatusCode
OK
PS C:\Scripts> $res.StatusDescription
OK

 

3. System.Net.WebClient

$url="http://www.cnn.com"
$wc = new-object net.webclient
$html = $wc.DownloadString($url)

 

There's is still a lot to investigate on this classes and its methods and this post can be only the tip of the iceberg. Personally, I prefer to use the System.Net.WebClient DownloadString method. It's quick and short to type. I don't want to rely on any methods to query responses based on status codes.
In my scripts I choose to get the document text and query it for a matching string.
I do it because if the target web server redirects you (which happens in most cases) to another page using the Server.Transfer method (e.g., 404 - page not found) than you
wont get 404, you'll get back "OK" or 200.

 

Here is another example. Frequently, I need to check if one of my web server on the Internet is listed in CBL's (Composite Blocking List) database as a spam source. This site is one of the most important spam databases. If you're server is listed there it is more likely that you are listed on numerous spam databases on the web. Most of them will simply query CBL.

 

$ip = "<WebServerIP>";
$url = "http://cbl.abuseat.org/lookup.cgi?ip=$ip";
$lookup = "^IP Address $ip was not found.*";
$wc = (new-object net.webclient).DownloadString($url);

if($wc -match $lookup){
    "Listed";
} else{
    "Not Listed";
}

 

Enjoy,

Shay

Monday, January 29, 2007

Automated Web forms


The listed function will Auto Login into Gmail. You can include it in the your Profile for fast execution. BTW, setting the value of a text input in PowerShell doesn’t follow the VBScript syntax, and so :

$ie.document.FormName.InputName.value = "something" will raise an error: Property 'value' cannot be found on this object; make sure it exists and is settable. At line:1 char:18 + $ie.theForm.TheInputName.v <<<< alue="something"

The code also implements the Get-Credential cmdlet. You can prompt the user to enter his credentials in a relative "secure" way (10x to /\/\o\/\/ ThePowerShellGuy for his help).

function Login-GMail{
    param(
        [string]$uname,
        [string]$url="http://www.gmail.com",
        [bool]$cookie=$false
    )

    $creds = get-credential $uname
    $pass = $creds.GetNetworkCredential().Password
    $ie=new-object -com internetexplorer.application
    $ie.visible=$true $ie.navigate($url)
    while($ie.ReadyState -ne 4) {start-sleep -m 100}     
    $ie.document.getElementById("Email").value=$uname     
    $ie.document.getElementById("Passwd").value = $pass     
    $ie.document.getElementsByName("PersistentCookie") | foreach {$_.checked=$cookie}     
    $ie.document.getElementById("gaia_loginform").submit()
}
Set-Alias gmail Login-Gmail

To activate it just type: gmail yourAccountName

$hay