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

Wednesday, October 4, 2017

Powershell, Adding Autocomplete to a Function

tldr: Add the ValidateSet attribute to a parameter. Like this: [ValidateSet("value 1", "value 2", "value etc")]$parameter or more verbosely:
function Get-Something(
    ValidateSet("value 1", "value 2", "value etc")]
    $parameter) {
    Write-Host "hi"
}
Just figured that out. Much bigger post here.

Monday, March 17, 2014

Dilbert Me 2

The previous powershell script for dilbert broke. It seems the cartoons aren't sequential. This is try #2. 

$url = "http://www.dilbert.com" 
$httpRequest = [Net.WebRequest]::create($url)

$response = $httpRequest.GetResponse()
$stream = $response.GetResponseStream()
$buffer = @()
$binaryReader = New-Object System.IO.BinaryReader($stream)

$tempBuffer = $binaryReader.ReadBytes(1024)
while($tempBuffer.Length -eq 1024) { 
    $buffer += $tempBuffer
    $tempBuffer = $binaryReader.ReadBytes(1024)
}

$dilbert = [System.Text.ASCIIEncoding]::UTF8.GetString($buffer)

$url = "http://www.dilbert.com/" + [System.Text.RegularExpressions.Regex]::Match($dilbert, "src=.*strip.gif").Value.Substring(5)

$url 

$httpRequest = [Net.WebRequest]::create($url)

$response = $httpRequest.GetResponse()
$stream = $response.GetResponseStream()
$buffer = @()
$binaryReader = New-Object System.IO.BinaryReader($stream)

$tempBuffer = $binaryReader.ReadBytes(1024)
while($tempBuffer.Length -eq 1024) { 
    $buffer += $tempBuffer
    $tempBuffer = $binaryReader.ReadBytes(1024)
}

$buffer += $tempBuffer
$tempFile = [System.IO.Path]::GetTempFileName() + ".gif"
[System.IO.File]::WriteAllBytes($tempFile, $buffer)
.$tempFile

Tuesday, March 11, 2014

Dilbert Me!

My RSS reader (feedly) doesn't handle Dilbert well. Probably because they want me to view all the advertising surrounding the daily Dilbert cartoon. So it opens up an external browser and forwards me to Dilbert.com from the RSS reader. This is annoying. This powershell script opens up today's Dilbert and shows just the strip. I should wrap this in it's own RSS feed... eventually

$startDate = New-Object DateTime(1425, 9, 14)
$days = [DateTime]::Now.Subtract($startDate).Days
$hundredThousands = [Math]::Floor( $days / 100000)
$tenThousands = [Math]::Floor( ($days % 100000)/10000)
$thousands = [Math]::Floor( ($days % 10000)/1000)
$hundreds = [Math]::Floor( ($days %1000) /100)
$remainder = [Math]::Floor( ($days %100))
#http://dilbert.com/dyn/str_strip/000000000/00000000/0000000/200000/10000/4000/900/214940/214940.strip.gif
$url = "http://dilbert.com/dyn/str_strip/000000000/00000000/0000000/" + $hundredThousands + "00000/" + $tenThousands + "0000/" + $thousands + "000/" + $hundreds + "00/" + $days + "/" + $days + ".strip.gif"

$httpRequest = [Net.WebRequest]::create($url)

$response = $httpRequest.GetResponse()
$stream = $response.GetResponseStream()
$buffer = @()
$binaryReader = New-Object System.IO.BinaryReader($stream)

$tempBuffer = $binaryReader.ReadBytes(1024)
while($tempBuffer.Length -eq 1024) { 
 $buffer += $tempBuffer
 $tempBuffer = $binaryReader.ReadBytes(1024)
}

$buffer += $tempBuffer
$tempFile = [System.IO.Path]::GetTempFileName() + ".gif"
[System.IO.File]::WriteAllBytes($tempFile, $buffer)
.$tempFile

Monday, June 17, 2013

How to write a loop, or lambda expression, in the immediate window, part 2

$dte is the key.

That whole nuget package manager console window, that is a powershell window, that gives you easy access to the visual studio automation model, is neat, very powerful, and, as I have discovered, a treasure trove of Visual Studio arcana.

EnvDTE.DTE is easy to get at when you are in the context of an add-in that you have written yourself. Exposing it in ready made powershell window, is a complex and involved trick. Writing that whole powershell console as an add-in inside of Visual Studio, after reading the source code at nuget.codeplex.com, appears to be an elegant work of coding art.

But.. back to $dte, my favorite powershell-nuget-visualstudio variable. Here is the code that worked the magic and populated the variable inside of powershell:

 
        [System.Diagnostics.CodeAnalysis.SuppressMessage(
           
"Microsoft.Reliability",
           
"CA2000:Dispose objects before losing scope",
            Justification =
"We can't dispose it if we want to return it.")]
       
private static Tuple CreateRunspace(IConsole console, string hostName)
        {
            DTE dte = ServiceLocator.GetInstance();
InitialSessionState initialSessionState = InitialSessionState.CreateDefault();
            initialSessionState.Variables.Add(
               
new SessionStateVariableEntry(
                   
"DTE",
                    (DTE2)dte,
                   
"Visual Studio DTE automation object",
                    ScopedItemOptions.AllScope | ScopedItemOptions.Constant)
            );
// this is used by the functional tests
           
var packageManagerFactory = ServiceLocator.GetInstance();
           
var pmfTuple = Tuple.Create<string, object>("packageManagerFactory", packageManagerFactory);
Tuple<string, object>[] privateData = new Tuple<string, object>[] { pmfTuple };
var host = new NuGetPSHost(hostName, privateData)
            {
                ActiveConsole = console
            };
var runspace = RunspaceFactory.CreateRunspace(host, initialSessionState);
            runspace.ThreadOptions = PSThreadOptions.Default;
            runspace.Open();
//
           
// Set this runspace as DefaultRunspace so I can script DTE events.
           
//
           
// WARNING: MSDN says this is unsafe. The runspace must not be shared across
           
// threads. I need this to be able to use ScriptBlock for DTE events. The
           
// ScriptBlock event handlers execute on DefaultRunspace.
           
//
            Runspace.DefaultRunspace = runspace;
return Tuple.Create(new RunspaceDispatcher(runspace), host);
        }
 
 
 
So here is what I learned from strolling down this rabbit hole.
  1. They brute forced the whole console window. They didn't recycle any sort of existing powershell or command window. They wrote a new one and dealt with all the keypress by keypress nastiness that is involved therein.
  2. $dte is actually spelled $DTE, and just a variable passed into a Runspace through its InitialSessionState.
  3. OpenSource code is fun.

Also, and unrelated to codeplex and nuget, if you want to create a headless $dte object, or rather one connected to a new instance of visual studio 2012, that is simply:

$dte = New-Object -comobject VisualStudio.DTE.11.0

Getting the running obect is done like this:

$dte = [System.Runtime.InteropSrevices.Marshal]::GetActiveObject("VisualStudio.DTE.11.0")

Wednesday, June 12, 2013

How to write a loop, or lambda expression, in the immediate window

First, you can't write lambda expressions in the immediate window. There are some very good, boring reasons why this is the case. Jared Par explains here...

However, what you really wanted to do is write a loop inside the immediate window because there is some particular debugging goal that you are trying to achieve. This post is about how you can do that.

For example, let's say we have an array of a large number of elements, 1000 or so should do. Let's also say that there is one piece of data in that array that is relevant. We wish to inspect each element individually and test the validity of each item. The following code snipped creates this situation.

static void Main(string[] args)
{ 
  List<int> ints = new List<int>();
  for (int i = 0; i < 1000; i++)
  {
    ints.Add(i);
  }
 
 
  Random random = new Random();
  ints[random.Next(1000)] = -12;
  Console.ReadLine();
}

In this artificial case we're looking for the index of the element in the array that is equal to -12.

The immediate window forces us to do this one item in the array at a time. Potentially taking 1000 user-interactive steps.

Since that method sucks, here's an alternative:
  1. Run the program in the debugger and set a breakpoint on the ReadLine() statement.
  2. Open up the nuget package manager console.
  3. Write some clever powershell that does the evaluation and looping for us.
The clever bit of powershell code that is necessary starts with something like this:

$dte.Debugger.GetExpression("expression", 1, $true)

$dte is the variable that contains the Visual Studio automation model.
Documentation about $dte is here.

In our case, the completed powershell expression looks like this:

for($i = 0; $i -lt 1000; $i++) { $a = $dte.Debugger.GetExpression("ints[$i]"); if ($a.Value -ne $i) { Write-Host $a.Value $i } }

Or, broken into multiple, more readable lines:

for($i = 0; $i -lt 1000; $i++) {
  $a = $dte.Debugger.GetExpression("ints[$i]");
  if ($a.Value -ne $i) {
    Write-Host $a.Value $i
  }
}

This rather neatly writes out the index we're looking for and the value found there. 



















The anomalous value (-12) wound up in the 604th element of the array. Groovy.

Most programmers aren't going to do this. It requires good knowledge of powershell, some knowledge of the Visual Studio automation model, and an interesting and difficult debugging problem before it is useful.

But it is fun.

Thursday, August 16, 2012

Fun with active Directory

How to find out what ActiveDirectory groups you, or anyone else belongs to.

$de = New-Object System.DirectoryServices.DirectoryEntry          
$searcher = New-Object System.DirectoryServices.DirectorySearcher($de) 
$searcher.Filter = "(sAMAccountName=qatest13)" 
$result = $searcher.FindOne()        
$result.Properties

Also extremely useful, and from SysInternals, is Active Directory Explorer.

LDAP factors prominently in all of this. Someday I might like to have some confidence in what to use as a filter in the searcher. But for now, I'll settle for making a note about what works and not caring why.
(SAM-Account-Name)



Wednesday, May 9, 2012

Fizz Buzz in powershell

For fun, I thought I’d see if I could write Fizz Buzz in powershell.
1 .. 100 | foreach { if ($_ % 15 -eq 0) { Write-Host "FizzBuzz" } elseif ( $_ % 3 -eq 0) { Write-Host "Fizz" } elseif ($_ % 6 -eq 0) { Write-Host "Buzz" } else { Write-Host $_ } }
Or, if you prefer multiple lines:
1 .. 100 | foreach 
{ 
    if ($_ % 15 -eq 0) { 
        Write-Host "FizzBuzz" 
    } elseif ( $_ % 5 -eq 0) { 
        Write-Host "Fizz" 
    } elseif ($_ % 3 -eq 0) { 
        Write-Host "Buzz" 
    } else { 
        Write-Host $_ 
    }
}
Not to hard, but why stop there?

F# Fizz Buzz

[1..100] |> Seq.map( function      | x when x % 15 = 0 -> "BizzBuzz"     | x when x % 5 = 0 -> "Bizz"     | x when x % 3 = 0 -> "Buzz"      | x -> string x ) |> Seq.iter(printfn "%s" ) ;;

TSQL Fizz Buzz


My first attempt:



DECLARE @i INT
SELECT @i = 0

WHILE @i < 100
BEGIN
SELECT @i = @i + 1
IF (@i % 15 = 0)
PRINT 'FIZZBUZZ'
ELSE IF (@i % 5 = 0)
PRINT 'FIZZ'
ELSE IF (@i % 3 = 0)
PRINT 'BUZZ'
ELSE
PRINT @i
END 


Not very TSQL-y so I tried again:

DECLARE @i INT
SELECT @i = 0

WHILE @i < 100
BEGIN
SELECT @i = @i + 1
PRINT CASE WHEN (@i % 15 = 0) THEN 'FIZZBUZZ'
WHEN (@i % 5 = 0) THEN 'FIZZ' 
WHEN (@i % 3 = 0) THEN 'BUZZ'
ELSE CAST(@i AS NVARCHAR(MAX))
END
END


A little better, but I found an even better one on the interweb.

WITH Numbers(Number) AS (
  SELECT 1
  UNION ALL
  SELECT Number + 1
  FROM Numbers
  WHERE Number < 100
)

SELECT
  CASE
    WHEN Number % 3 = 0 AND Number % 5 = 0 THEN 'FizzBuzz'
    WHEN Number % 3 = 0 THEN 'Fizz'
    WHEN Number % 5 = 0 THEN 'Buzz'
    ELSE CONVERT(VARCHAR(3), Number)
  END
FROM Numbers
ORDER BY Number


This one is full of interesting things. The recursive function at the start is going to take me some time to digest, but it is also very cool.

So once more in javascript:


Javascript Fizz Buzz

for( i = 1; i < 100; i++) {
if (i % 15 == 0) {
console.log("FizzBuzz");
} else if ( i % 3 == 0) {
 console.log( "Fizz" );
} else if ( i % 5 == 0) {
console.log( "Buzz" );
} else {
console.log( i );
}
}

The only thing interesting here is that you can type this in any browser’s javascript console (F12 to open it up).  Other than that, it is boring.


Tuesday, August 9, 2011

How to get powershell syntax highlighting in HTML

Step 1: Use PowerGUI.
Aside from the code-highlighting, it's all kinds of awesome.
Step 2: Select the code
Step 3: From the Menu: Edit->Copy As->HTML
Step 4: Paste and enjoy in your Blog.

Finding locked files with OpenFiles

OpenFiles is a command line executable that has been around since XP. It isn't a powershell command so it doesn't produce nice PSObjects to play with, just raw text.

To find a particular file in the daunting amount of output, I do this:

OpenFiles | %{ if ($_.contains("search string")) { $_ } } 

Powershell locks loaded assemblies. Remove-Module doesn't help.

I was testing an assembly generated by Visual Studio. I imported the module into powershell via Import-Module, created the class I wanted, invoked its members, and viewed the results. Then I tweaked the project in Visual Studio and rebuilt. Powershell had the output assembly loaded and locked, so the build failed.

No news there.

The first workaround was to just close powershell and reopen it.

But! I figured I could call Remove-Module and get passed the lock without actually closing Powershell...
While this seemed like a good idea. It failed. Powershell didn't remove the lock it had on the imported assembly and it was still listed in the modules that Powershell was using. Remove-Module didn't remove the module. It just stopped showing up in Get-Modules. In fact, the variables created using the .net dll were still alive in the powershell process. Remove-Module was no solution.

Next! I figured that I would load the module inside of a powershell session and then unload the session.
Enable-PSRemoting
$session = $New-PSSession
Enter-PSSession $session
#Do Stuff
Exit-PSSession
Remove-PSSession $session

This failed as well. :(

Next I figured that I could create an AppDomain, create a Runspace in the AppDomain, do stuff, and then unload the AppDomain. I'm certain that this approach would work, but it isn't worth the time, especially since the following pseudo-shadow copy solution will work just fine:

$fileName = [System.IO.Path]::GetTempFileName()
[Environment]::CurrentDirectory = "myProjectDirectory\bin\x86\Debug"
[System.IO.File]::Copy("MyDll.dll", $fileName + ".dll")
Import-Module ($filename + ".dll")

And thus the module is loaded, and doesn't lock the Visual Studio output files.

Monday, March 21, 2011

Loading the functions from a powershell script into session memory

.
The answer is ".".
Used like this:
. .\ApowershellScript.ps1
And then within the same powershell session I could do this:
SomeFunctionFromTheAforementionedScript ARandomArgument
And it would work.

I had been calling Process.Start, but the call started failing once I tried adding the call to the powershell function within it.
So this did not work:
1 ProcessStartInfo info = new ProcessStartInfo("powershell.exe");
2 info.Arguments = "{ . C:\\LivingRoom\\ir.ps1; sendIR " + command + " }";
3 info.RedirectStandardError = true;
4 info.RedirectStandardOutput = true;
5
6 info.UseShellExecute = false;
7
8 System.Diagnostics.Process process = Process.Start(info);

So this is what I did get to work:

1 Runspace rs = RunspaceFactory.CreateRunspace();
2 rs.Open();
3
4 Pipeline pipeline = rs.CreatePipeline();
5 Command command3 = new Command(" . C:\\LivingRoom\\ir.ps1", true, false);
6 Command command4 = new Command(" sendir " + command, true);
7 pipeline.Commands.Add(command3);
8 pipeline.Commands.Add(command4);
9 pipeline.Invoke();

It's all about the .

In order to use a Runspace in C#, I had to know the super-secret location of the .net assembly that contained the Runspace code.
C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll
The fact that they hid it is this odd location is weird. :P
Oh well.

Saturday, March 19, 2011

World of Warcraft Automation using Coded UI Tests from Visual Studio 2010

Previously I discussed automating repetitive tasks in World of Warcraft using powershell. While that works well, there are some situations where the only thing that will work is a mouse click. SendKeys makes it easy to send keyboard input to a window, but for some reason, I could not find an easy way of sending mouse input using a .Net API. "Easy" is the key word here, I could always try sending a message directly to the window through the Windows API, or involve some expensive third party automated testing tool.

I eventually stumbled upon a new feature in Visual Studio 2010: a coded UI test. The tests themselves are easy to create, the wizard in VS walks you through them excellently. There are plenty of resources on the net that describe how to use this feature in VS, so I'll spare you a redundant and feeble attempt at doing that, and show you how to integrate the result into a powershell script for easy manipulation.

The coded UI test runs very well inside of Visual Studio, but we need to run it externally. The compiled dll from the test project doesn't run by itself though, we require a utility called MSTest to run it.

The finished powershell script integrated with MSTest, looks like this:

Import-Module C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF\UIAutomationClient.dll
$a  = [System.Windows.Automation.AutomationElement]::RootElement.FindAll([System.Windows.Automation.TreeScope]::Descendants, [System.Windows.Automation.Condition]::TrueCondition) 
$wow = $a | Where { $_.Current.Name -eq "World of Warcraft" } 
$pattern = $wow.GetCurrentPattern([System.Windows.Automation.WindowPattern]::Pattern)
$pattern.SetWindowVisualState([System.Windows.Automation.WindowVisualState]::Normal)
for($i = 0; $i -lt 80; $i++) { 
     $mstest = "C:\program files (x86)\Microsoft Visual Studio 10.0\common7\ide\mstest.exe"
     Push-Location
     Set-Location "C:\Users\Ogre\Desktop\SVN\Powershell Samples\"
     & $mstest "/testcontainer:testproject1.dll"
     Pop-Location
     Sleep 4
     [System.Windows.Forms.SendKeys]::SendWait("=")
}

The Visual Studio test project was compiled to testproject1.dll and the output was copied into the same directory as this powershell script.

Creating a dll for a particular UI action in World of Warcraft as shown here does take a bit of doing, it certainly isn't as easy as using SendKeys, but you can, using this technique, automate any action in the UI, even the ones that Blizzard ordinarily has blocked from macro and lua programmatic usage.

Note that this only allows for automation of mindless repetitive tasks, if you want a full fledged bot, this falls far short.

Tuesday, March 8, 2011

Android TV Remote

TV remotes are simple devices. All that it takes to make one is an IR emitting diode and a small amount of logic to make the diode blink at the right intervals for the TV to interpret.
The total cost of the materials involved in the construction of such a device is small, probably 5$ at the most. I recently bought a TV remote from Radio Shack and took it apart to confirm the components involved. The device was nearly entirely molded plastic and buttons, plus the one IR diode and the one small chip to control it.

Now, I'm a very lazy person, as this blog post clearly demonstrates, so instead of keeping track of many small fist sized electronic devices that are involved with remote communications, I only want to keep track of only one -- my phone.
This would be a wonderful brilliant solution and a major selling point for whatever phone had incorporated the 5 dollars worth of parts required to make this work, but alas, I know of no phone that currently incorporates an IR LED.
>:P

But my laziness will not be denied, so after a bit of searching on the interwebs, I found a company called global cache which makes devices that facilitate laziness. Particularly ethernet connected IR emitters. So my solution begins to look like this:
Brilliant! Except that is not what I'm going to do. For one thing I opted for a GC-100 which is wired, not wireless. It also connects a relay, a serial, and 3 IR ports via TCP/IP. One of the IR ports has to be used to connect an IR Blaster which actually emits the IR signal.
Brilliant! But android-java is not my forte. So I made a solution that looks like this:
Well, I've removed the whole point of this exercise, which is to control the TV from my phone, but I'll add that back in later. In the meantime, the powershell script is exactly what I want to prototype the application and test that this much, at least, does work.

$msgOnOff = "sendir,2:1,1,37000,1,1,333,167,21,20,21,20,21,61,21,20,21,20,21,20,21,20,21,20,21,61,21,20,21,20,21,61,21,61,21,61,21,20,21,61,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,61,21,61,21,61,21,61,21,61,21,61,21,61,21,61,21,1576,333,83,21,740" + [char]::ConvertFromUtf32(13)
$msgMute = "sendir,2:1,1,37000,1,1,333,166,21,20,21,20,21,62,21,20,21,20,21,20,21,20,21,20,21,62,21,20,21,20,21,62,21,62,21,62,21,20,21,62,21,20,21,62,21,20,21,62,21,62,21,20,21,20,21,20,21,62,21,20,21,62,21,20,21,20,21,62,21,62,21,62,21,1572,333,84,21,740" + [char]::ConvertFromUtf32(13)
$msg = $msgOnOff
$ipaddress = [System.Net.IPAddress]::Parse("192.168.1.70")
$ipendpoint = New-Object System.Net.IPEndPoint -ArgumentList $ipaddress, 4998
$addressFamily = [System.Net.Sockets.AddressFamily]::InterNetwork
$socketType = [System.Net.Sockets.SocketType]::Stream
$protocolType = [System.Net.Sockets.ProtocolType]::Tcp
$socket = New-Object System.Net.Sockets.Socket -ArgumentList $addressFamily, $socketType, $protocolType
$socket.Connect($ipaddress, 4998)
$bytes = [System.Text.ASCIIEncoding]::ASCII.GetBytes($msg)
#$bytes
$socket.Send($bytes)
$socket.Close()

Running this script enabled me to turn the TV on and off programmatically, proving that I had the hardware set up right and that the whole concept would work. The strings: $msgOnOff and $msgMute were taken from using an IR learner and Global Cache's eLearn software.  It took me a bit of fiddling to get the  [char]::ConvertFromUtf32(13) at the end of the strings figured out, and until I did, the script did not work. 


So the next thing that I did was set up a web service that would launch the powershell script. This would enable me to test the set up with a simple web page. That solution looked something like this: 

The web service code looks like this: 


1 [OperationContract]
2 [WebGet]
3 public void ToggleMute()
4 {
5     ProcessStartInfo info = new ProcessStartInfo("powershell.exe");
6     info.Arguments = "-f \"C:\\LivingRoom\\sendirMute.ps1\"";
7     info.RedirectStandardError = true;
8     info.RedirectStandardOutput = true;
9
10     info.UseShellExecute = false;
11
12     System.Diagnostics.Process process = Process.Start( info);
13     return;
14 }

 That code runs a bit slow, so there's about a one second delay between when you launch that code and the TV actually turns off (or mutes itself in this case). I'll have to revisit this in the future and see if I can get it to run more quickly using runspaces or some other trick. 


And then there's the ajax that I use to call the web service: 

    function OnOff() {
        $.ajax({
            url: 'LivingRoom.svc/ToggleOn',
            type: "GET",
            cache: false
        });
    }


Once I verified that this worked from a browser, I was able to publish the website to my local server, and browse to it with my phone's browser, and click on the button that I put on the web page and I finally had my phone operating as a TV remote. 

At this point, the solution works with any device that has a browser (blackberry, iphone, android, random laptop). I could use windows scheduler to toggle the mute or on/off at any time (though I don't know how that would be useful). But what I really want it a native android application that is the User Interface, and not a web page, so after creation of an Android App the solution looks like this: 


public class NotesList extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final Button button = (Button) findViewById(R.id.Button01);
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                HttpClient httpClient = new DefaultHttpClient();
                HttpContext localContext = new BasicHttpContext();
                HttpGet httpGet = new HttpGet("http://192.168.1.76/LivingRoom/LivingRoom.svc/ToggleMute");
                try {
                    httpClient.execute(httpGet, localContext);
                } catch (ClientProtocolException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }
}


So I've created an Android based TV remote, woot. 

Here's a list of some of the technologies and programs that I used in this little exercise:
Powershell
IIS
aspnet_regiis.exe
Visual Studio 2010
Javascript/JQuery/Ajax
C# Web Service
Eclipse
Windows 7 
Ubuntu Linux
Android Java
Enterprise Architect (for the diagrams)
Paint (for prepping the diagrams)