Google
 

Wednesday, April 22, 2009

Oracle buys Sun !!

OK, I think you already know this. But it's not the news I'm talking about. I'm talking about the implications.

I did not use Java technology a lot, I admire it, but I cannot consider myself as a Java developer. However, having Java technology in our world and it's competition with Microsoft's .net framework is a healthy thing. It gives us options.
Some Java developers were worried after news about the deal has spread. I think that Oracle + Java has been and will stay a good choice to build enterprise applications. Maybe the future will carry news about better and better RIA applications built with Java platform.




What I really care about and made me worried is the future of MySQL, which is the most popular open source database that has a free community edition.
How is this related to MySQL? Here is the story:

MySQL has a pluggable database engine architecture. So it has many database engines to choose from, and you deal with them all using the same SQL dialect.
One famous engine is the InnoDB engine, which is transactional and high performance database engine that was widely used by MySQL users. InnoDB was developed by Innobase, a Finnish company.
Oracle acquired Innobase, which caused worries about the future of the transactional engine. Sun bought MySQL. And MySQL released the Falcon storage engine.



Now, what is the future of MySQL under the control of Oracle, the database giant? The problem is not only that Oracle may kill MySQL gradually (I think it won't do it directly). But is that MySQL engineers started to leave Sun after Oracle's deal. (more about this in this article).

So. Big fishes eat small fishes. It's the turn of open source advocates and MySQL users to have their word.

Saturday, April 18, 2009

Calling a PowerShell script in a path with a white space from command line

I stuck in this problem once, so here is a solution in case you face it.
First, how to call a script from PowerShell console when the script file path contains white space? because executing this:
PS C:\> c:\new folder\myscript.ps1 param1
will give this error:
The term 'c:\new' is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again.

Putting the path between quotations like this:
PS C:\> "c:\new folder\myscript.ps1" param1
Will lead to:
Unexpected token 'param1' in expression or statement.

And the solution is to use the Invoke Operator "&", which is used to run script blocks
PS C:\> & 'c:\new folder\myscript.ps1' param1

So farm so good. Now coming to the next part which is calling this from command line.
Executing a PowerShell script from command line is as easy as:
C:\Documents and Settings\Hesham>powershell c:\MyScript.ps1 param1

This is fine as long as the script path has no spaces. For example, executing:
C:\Documents and Settings\Hesham>powershell c:\new folder\MyScript.ps1 param1
Again gives:
The term 'c:\new' is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again.


With the help of PowerShell -?, here is a solution:
C:\Documents and Settings\Hesham>powershell -command "& {&'c:\new folder\MyScript.ps1' param1}"

Tada!!

Saturday, March 7, 2009

Why should you learn PowerShell?

Whether you are a software developer, a tester, a system administrator, or even a regular user, PowerShell has something for you to offer.

It's amazing capabilities open many possibilities for you and it can be used in several scenarios:
  • For system administrators: quick and easy way to deal with the system in a consistent way. You'll have the power of many built-in commands, the .net CLR. Using it, you can perform several tasks like managing the file system and permissions, monitor even log, work with Active Directory. And so much more.
  • As a Developer: you can use PowerShell commands to automate some systems like exchange server from your application. Most Microsoft server products support or will support PowerShell as a programmable interface to automate the product. You can also use it to check environment issues if you have a production or testing environment issues that you suspect it's root cause to be environment related.
  • As a tester: PowerShell can be used for testing automation. With its easy to use commands and the simple syntax, I believe it's very suitable for this purpose. Have a look at: Why Should I Test With PowerShell?

If you want to get a high level image about what PowerShell can do for you and the flexibility it provides, you can watch this video by Jeffrey Snover the architect of PowerShell:

Monday, February 2, 2009

How to know Active Directory attribute names

When dealing programmaically with active directory objects using .net code, VBScript or PowerShell, you need to set values of attribues you find in the "Active Directory Users and Computers" Snap-in (run dsa.msc). But these names are not always the same as the names used when setting attribute values in code. So how to know the attribute names?

I stumbled upon a nice msdn page that has the Mappings for the Active Directory Users and Computers Snap-in. It has has links to object type specific UI labels to attribute names.
For example, the User Object User Interface Mapping page shows that the Office UI label maps to physicalDeliveryOfficeName. How could you guess it?

Friday, January 30, 2009

Working with Active Directory using PowerShell

Working with Active Directory is one of the important administrative tasks. VBSctipt was the most used language for administartors to automate repetitive tasks.
Now, windows PowerShell is the future, so it's important to know how to use it to work with Active Directory.
I'll provide a simple example that should clarify some concepts. In this scenario, it's required to set the email attribute of all users under a certain OU (Organaizational Unit) in the format: sAMAccountname@domainname.com and output the results to a text file.
PowerShell 1.0 does not have specific built in Cmdlets to handle active directory objects. But it has a basic support for [ADSI]. This will not limit us as we still can use the .net class library easly in PowerShell.
Here is how the code works:


  • First we decclare a variable that holds the output file path:
    $filePath = "c:\MyFile.txt"

  • Then, create the root directory entry which represents the OU that we need to modify users under it. Note the LDAP: it tells: get the OU named "MyOU" from the domain "win2008.demo"
    $rootOU=[ADSI]"LDAP://ou=MyOU,dc=win2008,dc=demo"

  • We need to get all users under this OU, so we create a .net directory searcher instance using New-Object Cmdlet
    $searcher= New-Object System.DirectoryServices.DirectorySearcher

  • Setting the root of the search to the OU and the filter to find users only. and start to find all objects that match the filter:
    $searcher.searchroot=$rootOU
    $searcher.Filter = "objectclass=user"
    $res=$searcher.FindAll()

  • Initializing the output file by writing the string "Emails"
    "Emails:" Out-File -FilePath $filePath

  • Iterating on the results:
    foreach($u in $res)

  • Getting the user object and setting the mail attribute, and committing:
    $user = $u.GetDirectoryEntry()
    $name=$user.sAMAccountname
    $user.mail="$name@win2008.demo"
    $user.SetInfo()

  • Appending the mail to the output file (note the append parameter):
    $user.mail Out-File -FilePath $filePath -append

You can save these commands to a .ps1 file and execute from PowerShell, for example:
c:\filename.ps1
note that you need to execute Set-ExecutionPolicy RemoteSigned first.

And here is the complete code listing, note that no error checking or handling is included for simplicity.


#Set-ExecutionPolicy RemoteSigned

$filePath = "c:\MyFile.txt"

$rootOU=[ADSI]"LDAP://ou=MyOU,dc=win2008,dc=demo"

$searcher= New-Object System.DirectoryServices.DirectorySearcher

$searcher.searchroot=$rootOU
$searcher.Filter = "objectclass=user"

$res=$searcher.FindAll()

"Emails:" Out-File -FilePath $filePath
foreach($u in $res)
{
$user = $u.GetDirectoryEntry()

$name=$user.sAMAccountname
$user.mail="$name@win2008.demo"
$user.SetInfo()

$user.mail Out-File -FilePath $filePath -append

$user.psbase.Dispose()


}
$rootOU.psbase.Dispose()
$res.Dispose()
$searcher.Dispose()

Thursday, January 1, 2009

Articles I read in 2008

It's a new year, and it's time to share a list of most articles I read the last year. Hopefully you find it interesting and useful.

2007 list can be fond here

Friday, December 5, 2008

Handling errors when calling PowerShell using C#

In a previous post, I explained how to call PowerShell Commands from C# code in an easy way. But what about error handling?
First, we should know about the types of errors that need to be handled:
  • Exceptions due to error in syntax of the command or script.
  • Errors generated from commands themselves due to logical errors or invalid parameters.
Handling Exceptions:
Several exceptions can be thrown. The base for PowerShell exceptions is the System.Management.Automation.RuntimeException class. Exceptions can originate from bad syntax or calling invalid commands.
Handling this kind of errors follows the common exception handling in .net as this example shows:


try
{
using (RunspaceInvoke invoke = new RunspaceInvoke())
{
result = invoke.Invoke("dir " + "c:\\" + " -recurse -Filter *.exe");
}
}
catch (System.Management.Automation.RuntimeException ex)
{
Console.WriteLine(ex.Message);
//Specific handling for PowerShell errors
}
catch (Exception ex)
{
//general handling and logging
}

Command Errors:
These errors that commands return. For example, when you run this command in PowerShell while you don't have a Q drive:
dir Q:
You'll get this error:
Get-ChildItem : Cannot find drive. A drive with name 'q' does not exist.
At line:1 char:4
Which makes sense. But how to check for this kind of errors?
The Invoke method of the RunspaceInvoke class has an overload that accepts an IList as the 3rd parameter. This out parameter will contain a list of errors that has occurred.


IList errors;
using (RunspaceInvoke invoke = new RunspaceInvoke())
{
result = invoke.Invoke("dir " + "Q:\\" + " -recurse -Filter *.exe", null, out errors);
}

if (errors.Count > 0)
{
PSObject error = errors[0] as PSObject;
if (error != null)
{
ErrorRecord record = error.BaseObject as ErrorRecord;
Console.WriteLine(record.Exception.Message);
Console.WriteLine(record.FullyQualifiedErrorId);
}

return;
}

In the above code, I cast the error to PSObject and get its BaseObject and cast it to ErrorRecord which contains the error information.

An interesting part here, is that you can check the FullyQualifiedErrorId property which is a string to distinguish errors and create logic to handle specific errors. ErrorDetails property can also be checked. But be careful because it can be null.

I hope this post can make your programming with PowerShell easier.