June 13, 2009

Powershell and Event Logs

The Powershell blog posted an article on how easy it is to read the event log. I have used and continue to use logparser from powershell to read the event log as I always have though logparser would be faster. Could I be wrong? I'll run a test tonight and try and get the results in to you tomorrow. What do you you use to parse the event log in windows?

June 12, 2009

TGIF

Have a great weekend everyone. Seems like the weather cleared up just in time for the weekend.

Encrypt config using powershell

Here is a simple way to encrypt your config file using a powershell script:
Add-Type -Assembly System.Configuration

function Config-Encrypt {
param( [string] $appPath = $(throw "Path of config file is incorrect or missing."),
[string] $sectionName = $(throw "Section in config file is incorrect or missing.")
)

Write-Host "Encrypting config section..."

$config = [System.Configuration.ConfigurationManager]::OpenExeConfiguration((Convert-Path $appPath))
$section = $config.GetSection($sectionName)

if (-not $section.SectionInformation.IsProtected)
{
if(-not $section.SectionInformation.IsLocked)
{
$section.SectionInformation.ProtectSection("RSAProtectedConfigurationProvider");
$section.SectionInformation.ForceSave = $true
$config.Save([System.Configuration.ConfigurationSaveMode]::Modified);
}
}

Write-Host "Completed."
}
All you would have to do is then call it like this:
Config-Encrypt 'c:\DataConfiguration.config' 'connectionStrings'
To Decrypt,you can create a function called Config-Decrypt. The code is basically the same with some minor changes:
Add-Type -Assembly System.Configuration

function Config-Decrypt {
param( [string] $appPath = $(throw "Path of config file is incorrect or missing."),
[string] $sectionName = $(throw "Section in config file is incorrect or missing.")
)

Write-Host "Decrypting config section..."

$config = [System.Configuration.ConfigurationManager]::OpenExeConfiguration((Convert-Path $appPath))
$section = $config.GetSection($sectionName)

if ($section.SectionInformation.IsProtected)
{
if(-not $section.SectionInformation.IsLocked)
{
$section.SectionInformation.UnprotectSection();
$section.SectionInformation.ForceSave = $true
$config.Save([System.Configuration.ConfigurationSaveMode]::Modified);
}
}

Write-Host "Completed."
}

June 11, 2009

What a day!

Don't you hate when all day is just meeting after meeting after meeting? Time to go out and get a few drinks!

June 10, 2009

Active Directory Authentication in C#

There is a lot of code on the web that actually does exactly what this post discusses. Also, in later versions of .NET, Microsoft almost gave the code outright to us. However, the issue with many versions on the web and even the approach Microsoft takes (with the ActiveDirectoryMembershipProvider) is that they do LDAP binds which is slower than making the Win32 call. What is the performance difference? Well, I ran a quick test and the results were than LogonUser was about 5x faster! I have uploaded my code here which is basked off an ILogin and a Win32 Login. The basic idea being that perhaps one day we move away from Active Directory Authentication. Here is the ILogin interface:
    public interface ILogin
{
void Authenticate(string username, string password);
void Authenticate(string username, string password, string domain);
}
The Win32 example is below:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using JL.Framework.Security;
using JL.Framework.Security.Win32Authentication;

namespace Console
{
class Program
{
static void Main(string[] args)
{
string username = "joe";
string password = "mypass";
string domain = "domain"; //note this is not required as I point out it can be called from a config

ILogin login = new Win32Login();
try{
login.Authenticate(username, password, domain);
System.Console.WriteLine("Successfully authenticated!");
}
catch (AuthenticationException ex)
{
System.Console.WriteLine(ex);
}

username = Win32Login.ParseLogonName("domainA\\userA", out domain);
Debug.Assert(username == "userA");
Debug.Assert(domain == "domainA");

username = Win32Login.ParseLogonName("userB@domainB", out domain);
Debug.Assert(username == "userB");
Debug.Assert(domain == "domainB");
}
}
}
You should be able to use the code in any authentication system you may have written in .NET that talks to AD.

My Brute!

After a long day or a long meeting, you sometimes feel like you to need to just get up and scream or well play Punch Out. I saw this free online game called My Brute which is a step down from punch out, yet very funny. Take a look at it here.

June 9, 2009

Google Wave!

Google Wave and the response from Ozzie!

Gac Assemblies in Powershell

I first came across this on a post in StackOverflow about a month ago. The question was how to add assemblies to the Gac from a text file. Here is a (very) slightly modified solution from what I saw there:
sal -Name gacutil -Value $env:ProgramFiles'\Microsoft SDKs\Windows\V6.0A\bin\gacutil.exe'
filter gac-item { gacutil /nologo /i $_}
gc c:\list.txt | ?{$_ -like "*.dll"} | gac-item
The text file 'list.txt' would basically contain assemblies and their paths like:
C:\ICSharpCode.SharpZipLib.dll
c:\MyFile.dll
C:\MyAssemblyLocations\MyAssemblies\Test.dll
I was curious how easy it would be to just point to a folder and take all .dll files as opposed to looking at a text document. You can do that by modding the above script with this:
sl -Path $env:ProgramFiles\'MyBigProject\Bin'

foreach ($file in gci -Filter "*.dll" ) {
gacutil /nologo /i $file.Name
}
Powershell really makes things like this very simple.

Project Management Cartoon

This always makes me smile!

June 8, 2009

AzMan Bulk Import/Export Tool

Great, we are using AD as a backing store instead of XML because of scalability. The million dollar question to Microsoft a few years ago was "How do I get this from my Dev --> QA --> Prod domain?!?". Assuming no trusts (which should be the case), this means if I have for example 50 operations and 25 tasks, and 15 roles...this can be very tedious. It was for this reason that I created the original Bulk Import/Export tool. At the time, the tool was written to go from AD --> XML and then XML back to AD. This allowed a neat little import/export but SIDs were always messed up. Newer versions that were not released allowed from AD to AD using impersonation. Newer versions even included SQL store.

In this post, I am just going to link to my original version of the code which can be found here. Having said that, I will post shortly my updated version(s) of this code for people to use.

Post here if you have used this tool, as I am quite interested in how many people used it. I always get emails regarding it so I know that it is heavily used.

Log4Net and Powershell

Sure, why not! To be honest, I see no reason as we have other options in Powershell. Here is how you would do it:
Add-Type -Assembly System.Configuration
[System.Reflection.Assembly]::LoadFrom($MY_DIR + "\lib\log4net.dll")

#Reset
[log4net.LogManager]::ResetConfiguration()
#Configure
[log4net.Config.BasicConfigurator]::Configure()
$log = [log4net.LogManager]::getLogger("POShTest")

if($log.IsDebugEnabled)
{
$log.debug("Debug!")
}

$log.info("Info!")
$log.warn("Warn!")
$log.error("Error!")
$log.fatal("Fatal")

Connect to Network Drive using Powershell

In one of my applications using powershell, I often have to connect to various network drives. I saw that powershell has a cmdlet called New-PSDrive which should take care of this for me. However, I saw that it kept failing on the connection with the provider does not support the use of credentials. How am I going to connect without being able to use the -credential option?! Well, I figured I'd have to script it using posh and calling something else. This is what I came up with:
# Map a Drive and pass in the below params
function MapNetworkDrive($net_drive, $path, $user, $password) {
$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive($net_drive, $path, $false, $user, $password)
}

function RemoveNetworkDrive($net_drive){
try
{
$net = new-object -ComObject WScript.Network
$net.RemoveNetworkDrive($net_drive)
}
catch [System.Exception]
{
#Log
}
}

Load Assemblies in Powershell

There is a myriad of ways to do this, but I wanted to do it from a lib folder within my application as opposed to the GAC or by full path. It was actually quite simple:
# References
Add-Type -Assembly System.Configuration
[System.Reflection.Assembly]::LoadFrom($MY_DIR + "\lib\ICSharpCode.SharpZipLib.dll")

June 7, 2009

WolframAlpha

This is a cool site! Check it out.

Powershell Get MD5 For File

Often when comparing 2 files you have the following 3 options:
  • Date/Time Stamp
  • CRC Check
  • MD5 Check
Each one has a speed tag associated with it where date-time is fast and MD5 is a bit slower. MD5 will however give the best comparison check. Below is an example on how to get the MD5 hash associated with a file:
function Get-MD5File {
Param([string]$file)
$open = [System.IO.FileMode]("open")
$read = [System.IO.FileAccess]("Read")
$md5 = new-object System.Security.Cryptography.MD5CryptoServiceProvider
$fs = new-object System.IO.FileStream($file, $open, $read)
$Hash = $md5.ComputeHash($fs)
$fs.Close()
return $Hash
}

#test a file
$MD5File = Get-MD5File c:\test.pl
Write-Host $MD5File
I believe that the POSh community extensions located here has some easy way to do this as well.

Unit Testing a Powershell Script with NUnit

I saw this article a while back, but I figured I should re-post in case others have not seen it. The article can be located here. It is actually really interesting and worth the read.