July 12, 2010

Network Adapters with Powershell

Filed under: Script — Tags: — Kevmar @ 6:26 am

One of the first things I discovered with Windows 7 was that they moved access to network adapters. I had some quick way to get to it and now I need to visit a few more screens. Today a coworker was talking about that same issue. He wanted a faster way to get to it. My response was, “I bet we can do that with Powershell”. The most common reason we end up looking at network adapters is to change ip settings to static or to DHCP. The only other things we do can be done with IPConfig. So I set out to write a little powershell that would give a computer a static IP address.

This turned out to be very simple with the Win32_NetworkAdapterConfiguration WMI object. I can use it to manage everything that was done with the GUI. The usual way we set static addresses is by first taking the dhcp address, entering it as static to the computer, then go into the dhcp server and exclude that address.

Set-NetworkStatic.ps1

$NICs = Get-WMIObject Win32_NetworkAdapterConfiguration | where{$_.IPEnabled -eq “TRUE”}
Foreach($NIC in $NICs) {

    $IP =$NIC.IPAddress -match "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"

    $Subnet = $NIC.IPSubnet -match "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"

    $Gateway = $NIC.DefaultIPGateway
    $DNSServers = $NIC.DNSServerSearchOrder
    $Domain = $NIC.DNSDomain

    $NIC.EnableStatic($IP, $Subnet)
    $NIC.SetGateways($Gateway)
    $NIC.SetDNSServerSearchOrder($DNSServers)
    $NIC.SetDynamicDNSRegistration(“TRUE”)
    $NIC.SetDNSDomain($Domain)
}

And then a second script to set it back to DHCP.

Set-NetworkDHCP.ps1

$NICs = Get-WMIObject Win32_NetworkAdapterConfiguration | where{$_.IPEnabled -eq “TRUE”}
Foreach($NIC in $NICs) {

    $NIC.EnableDHCP()
    $NIC.SetDNSServerSearchOrder()
}

July 5, 2010

Chaocipher: the algorithm in PowerShell

Filed under: Script — Tags: — Kevmar @ 5:24 pm

Cypher Mysteries just revealed a old substitution cypher from 1918. Here is a detailed example on how to work the method by hand.  After I read both of those sites I decided to flesh out the code for it in PowerShell.  This turned out to be very easy to put to code.  Review the linked example then take a look at my PowerShell sample.

I used ArrayLists to hold the left and right alphabets. When I thought about the circular nature and shifting of the alphabets, linked lists where the first things to come to mind. I think this sample can easily be translated in to other languages.

# Kevin Marquette
# www.ithinkincode.com
$cipher = ""

for($index=0; $index -ne $message.length;$index++)
{
    # Find the plain text letter and shift it to the front
    while($message[$index] -ne $right[0])
        {
        $right.Add($right[0]); $right.removeat(0); # Shift left
        $left.add($left[0]);    $left.removeat(0); # Shift Left
        }
    $cipher += $left[0];   

    # move from zenith + 1 to nadar (zenith + 13) position
    $left.insert(14,$left[1]);
    $left.removeat(1);

    # rotate right one more letter
    $right.Add($right[0]);   $right.removeat(0);  #Shift left

    # move from zenith + 2 to nadar (zenith + 13) position
    $right.insert(14,$right[2]);
    $right.removeat(2);
}

Write-Host $cipher;

Thats the base implementation of the Chaocipher. Here is my full implementation that also includes decryption.

# Kevin Marquette
# www.ithinkincode.com

function get-chaocipher([string]$message = "WELLDONEISBETTERTHANWELLSAID", [string]$leftalphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ", [string]$rightalphabet="PTLNBQDEOYSFAVZKGJRIHWXUMC", [bool]$encrypt=1)
{
Write-Host "Message: $message";
Write-Host "Left: $leftalphabet";
Write-Host "Right: $rightalphabet";
Write-Host "Encrypt: $encrypt";

# Validate Input
if($message -cmatch "^[A-Z]+$")
    {Write-Host "Message is Valid";}
else
    {
    Write-Host "Message is not Valid";
    return;
    }
if($leftalphabet -cmatch "^[A-Z]{26}$")
    {Write-Host "Left is Valid";}
else
    {
    Write-Host "Left is not Valid";
    return;
    }
if($rightalphabet -cmatch "^[A-Z]{26}$")
    {Write-Host "Right is Valid";}
else
    {
    Write-Host "Right is not Valid";
    return;
    }

# I want to use a linked list to manage the rotations
$left = New-Object System.Collections.ArrayList
$right = New-Object System.Collections.ArrayList
$cipher = New-Object System.Collections.ArrayList

# convert left and right to linked lists
for($i=0;$i -le 25; $i++)
    {
        $left.add($leftalphabet[$i]);
        $right.add($rightalphabet[$i]);
    }

$cipher = ""

#for each letter in the message
for($index=0; $index -ne $message.length;$index++)
{
    # Find the plain text letter and shift it to the front
    while(($message[$index] -ne $right[0] -and $encrypt -eq 1) -or ($message[$index] -ne $left[0] -and $encrypt -ne 1) )
        {
        $right.Add($right[0]); $right.removeat(0); # Shift left
        $left.add($left[0]);    $left.removeat(0); # Shift Left
        }
    if($encrypt -eq 1)
        {$cipher += $left[0];}
    else
        {$cipher += $right[0];}

    # move from zenith + 1 to nadar (zenith + 13) position
    $left.insert(14,$left[1]);
    $left.removeat(1);

    # rotate right one more letter
    $right.Add($right[0]);   $right.removeat(0);  #Shift left

    # move from zenith + 2 to nadar (zenith + 13) position
    $right.insert(14,$right[2]);
    $right.removeat(2);
}
Write-Host $cipher;
}

#encrypt
get-chaocipher "WELLDONEISBETTERTHANWELLSAID" "HXUCZVAMDSLKPEFJRIGTWOBNYQ" "PTLNBQDEOYSFAVZKGJRIHWXUMC" 1
#decrypt
get-chaocipher "OAHQHCNYNXTSZJRRHJBYHQKSOUJY" "HXUCZVAMDSLKPEFJRIGTWOBNYQ" "PTLNBQDEOYSFAVZKGJRIHWXUMC" 0

Decryption is as simple as checking from the other list. All the other steps are the same.

June 26, 2010

Signing Powershell and Applications the easy way

Filed under: Script — Tags: , — Kevmar @ 4:19 pm

My last post showed you an easy way to sign windows scripting host files. The same thing is available for Powershell and other executables. I found a lot of complicated way to sign applications before I figured out that Powershell can sign them too. This still assumes you have a Code Singing Cert already. Here is my Powershell signing script

$cert = @(gci cert:\currentuser\my -CodeSigningCert )[0]
Set-AuthenticodeSignature $args[0] $cert

I save that in a file called SignScript.ps1 on my computer where my cert is installed into the local store. The script I want signed is passed as $args[0] from the command line like this:

PS C:\> .\SignScript.ps1 myScript.ps1
PS C:\> .\SignScript.ps1 myApp.exe

I take this one step further by adding a sign option on the right click context menu from explorer. This is very easy to set up if you get it working from the command line. From regedit, open HKEY_CLASS_ROOT, and find Microsoft.PowerShellScript.1 (and exefile). Under the key called Shell, add a key called “Sign”. This is what will show up in the context menu. Under the key you added, add a new key called “command”. Then set the default value on that “command” key to match this .reg file.

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Sign\Command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" \"-file\" \"C:\\Scratch\\Scripts\\SignScript.ps1\" \"%1\""

[HKEY_CLASSES_ROOT\exefile\shell\Sign\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" \"-file\" \"C:\\Scratch\\Scripts\\SignScript.ps1\" \"%1\""

Now when you right click a .ps1 or .exe file, you can digitally sign it.

March 8, 2010

Powershell: List the size of folders or sub folders

Filed under: Script — Tags: — Kevmar @ 6:29 am

I was wanting to see how big my users’ home folders are.  With out quotas in place, I decided to use powershell.  I put together a function that will list the size of a folder that I pass to it. I wrote it in a way that if I pass a collection of folders to it, it will list the sizes of those folders individually.   This way I can spot check individual folders or check every folder in the home folders location.

This works even better for me because I need it to list the sub folder of each folder in the home folder location.  My home folders are placed in department folders.  So I have to add that extra step to every script I use to make sure it processes at the right level.  Allowing my function to work on a collection of folders allows powershell to handle this for me. Here is the syntax in action:

#Single folder
PS> Get-Item . | Get-FolderSize

#Sub folders
PS> Get-ChildItem . | Get-FolderSize

#Sub Sub Folders
PS> Get-ChildItem . | %{Get-ChildItem $_.FullName} | Get-FolderSize

It is required that you pass your directory objects to it.  I may update it to allow you to pass a folder path later. But for my needs, this is exactly how I will use it in my scripts.  Here is the full code for Get-FolderSize:

function Get-FolderSize ($_ = (get-item .))  {
  Process {
    $ErrorActionPreference = "SilentlyContinue"
    $length = (Get-ChildItem $_.fullname -recurse | Measure-Object -property length -sum).sum
    $obj = New-Object PSObject
    $obj | Add-Member NoteProperty Name ($_.Name)
    $obj | Add-Member NoteProperty FullName ($_.FullName)
    $obj | Add-Member NoteProperty Length ($length)
    $obj | Add-Member NoteProperty MB ("{0,13:N2}" -f ($length / 1MB))
    Write-Output $obj
  }
}

March 2, 2010

Powershell Grep to find old server names in batchfiles

Filed under: Script,Uncategorized — Tags: — Kevmar @ 11:40 am

I was troubleshooting a user access problem today and found that they had a old mapping to an old server in the login script.  We just moved all our data to a different server so it was expected to have a few issues like this.  We do use DFS for most of our shares so the transition was very smooth for most people.  Just a few exceptions needed fixed.

I think we just over looked the log in scripts so I needed a script to check them all.  This is where I should just use grep but I wanted to see how to do it in powershell.  Here is the command I came up with:

PS> get-childitem \\domain\netlogon -include *.bat -recurse | select-string "oldserver"

Here is another way to do the same thing with a few shorcuts that could be easier to remember at the command line:

PS> cd \\domain\netlogon
PS> dir -recurse | select-string "oldserver"

dir is short for get-childitem.  If all you have are .bat files in netlogon you can skip the include.  If you have other install files or packages, use the include to save time.

Powered by WordPress