Click here to Skip to main content
Click here to Skip to main content

Deployment made simple using Powershell

By , 14 Dec 2006
 
Prize winner in Competition "C# Nov 2006"

Introduction

Powershell scripts allow you to take advantage of .NET libraries and write scripts which are almost as powerful as the .NET code itself. You can do many powerful operations like call external DLLs, use .NET namespaces like System.IO, System.Net, run processes and intercept output, call web services etc. The possibilities are endless. Here, I will show you a Powershell script which assists you in day to day deployment of websites. Everyday, we make changes to web projects, which need to be deployed to development servers, sometimes on beta servers, and finally on the production server. Using this script, you can automate all the manual work that you do again and again on your deployment package every time you upload your website to some server. We use this script in Pageflakes every single day during our local development server upload, beta release, and final production server release. All we do is run the script, go to the server, and extract a zip file on the web folder, and that's all. The new version gets deployed within two minutes without any manual work at all, and completely removes any possibility of human error during deployment.

Automating deployment

The Powershell script does the following for you:

  • Maintains different configuration information for different deployments. For example, different connection strings for development servers and production servers (one or more production servers).
  • Creates a deployment folder using the deployment date, time, and version so that you have a separate folder for each deployment and can keep track of things deployed on a day, e.g., 20061214-1.
  • Copies only the change files and some predefined files to the deployment folder. So, you don't deploy the whole website every day.
  • Copies the web.config and customizes the <appSettings>, <connectionString>, <assemblies> etc., as per the deployment configuration. For example, you can have different connection strings for different servers.
  • Updates all JavaScript files with a version number so that in every deployment, a new file gets downloaded by client browsers.
  • Updates default.aspx automatically with the modified script file name.
  • Compresses all JavaScript files that gets deployed.
  • Compresses all static HTML files using an Absolute HTML Optimizer.
  • Creates a zip file which contains the deployment package.
  • FTP the zip file to a target server.

After the deployment script runs, all you need to do is extract the zip file on the server and that's all!

You can easily FTP the modified files instead of copying only the zip file, by changing the FTP part at the end of the script.

Configuring the script

The script takes some command line parameters:

Param (
    $CONFIG = "alpha",  # Configuration setting.
                        # e.g. alpha, beta, release
    $VERSION = 1,     # Version number 
                    # for the deployment. Increase as you will
    [DateTime] $LAST_CHANGE_DATETIME = 
       [DateTime]::Now.AddDays(-10), # File change date to consider
    $FROM ="SampleWeb", # Location of web site.
                        # Relative path to the script
    $FTP = 1 ) # 1 - FTP to host. 0 - Don't FTP

The parameters are:

  • CONFIG - Defines the configuration, e.g., "alpha", "beta", "release".
  • VERSION - Version number that you increase on every deployment. Script files are suffixed with the version number.
  • LAST_CHANGE_DATETIME - Files modified after this date time is deployed.
  • FROM - Relative path to the website folder.
  • FTP - If 1, FTP the zip, otherwise don't.

Then, define the FTP configuration in the following block:

# FTP Configuration where the package is uploaded
$HOSTNAME = "ftp.pageflakes.com";
$UPLOAD_DIR = "updates"; # Folder where the final
                         # zip package is uploaded
$USER = "UserName"; # Enter a user name for FTP Server
$PASS = "Password"; # Enter a password for FTP Password

After that, some handy configurations:

# Exlude the following folder while copying files
$EXCLUDE_FOLDERS = @('\App_Data', '\temp');
    
$DEFAULT_ASPX = "Default.aspx"; # The aspx file where script tag
                                # references are updated with version no
$SCRIPT_FILES = @('Script.js'); # Script files which gets
                                # a version suffix added

$ASSEMBLIES_TO_REMOVE = 
  @('Microsoft.Build.Framework'); 
  # Unwanted assemblies inside <assemblies>

You can define which folders to exclude always in the deployment. For example, no need to deploy App_Data.

Also define the ASPX file name which gets modified with new script references automatically. The $SCRIPT_FILES array contains the list of script files which are suffixed with the version number on every deployment and <SCRIPT Src="..."> is modified accordingly.

$ASSEMBLIES_TO_REMOVE specifies the assembly names which are removed from web.config's <assemblies> block. Sometimes, it is necessary to remove assemblies which are not needed in the production server. For example, nunitframework.dll.

After that, you define the configurations for different deployment targets:

if( $CONFIG -eq "alpha" )
{
    $DB_HOST = "(local)";
    $DB_NAME = "AlphaDatabase";
    $CREDENTIAL = "trusted_connection=false;";
}
if( $CONFIG -eq "beta" )
{
    $DB_HOST = "(local)";
    $DB_NAME = "BetaDatabase";
    $CREDENTIAL = "trusted_connection=false;";
}
if( $CONFIG -eq "release" )
{
    $DB_HOST = "(local)";
    $DB_NAME = "ReleaseDatabase";
    $CREDENTIAL = "trusted_connection=false;";
}

Here, I have specified different connection strings for different deployment targets.

Copying only modified files

The script first gets all the modified files:

# Get the files which were changed
# after the $LAST_CHANGE_DATETIME
$changedFiles = get-childitem $srcPath 
   -exclude "*.log" -Recurse | 
   where { $_ -is [System.IO.FileInfo] 
   -and $_.LastWriteTime -ge $LAST_CHANGE_DATETIME 
   -or $_.Name -eq $DEFAULT_ASPX 
   -or $_.Name -eq "web.config" }

The query finds all the files modified after the specified change date. But it always includes Default.aspx and web.config as these two files are always deployed. This is a requirement in Pageflakes and that's why I have put it there. You can remove it if you don't want it.

The next step is to decide the relative path for each file inside the deployment folder and copy the files from the source folder to the destination folder:

foreach( $file in $changedFiles )
{
    [string]$filePath = $file.ToString();
    [string]$relativePath = 
      $file.DirectoryName.substring($srcPath.Length);
    
    # if the file is in one of the excluded folders, don't copy
    $canCopy = 1;
    foreach( $excludeFolder in $EXCLUDE_FOLDERS )
    {
        if( $relativePath.StartsWith($excludeFolder) )
        {
            $canCopy = 0;
        }
    }

Before copying a file, it checks if the relative path contains any of the excluded folders.

If the folder is valid, copy the file. It also ensures the directory structure is created before copying the file:

if( $canCopy -eq 1 )
{
    # if the relative path contains a subdirectory,
    # then create a subdirectory under the deploy path
    [string]$copyPath = [System.IO.Path]::Combine( 
         $deployPath, $relativePath.TrimStart('\') );    

    if( ![System.IO.Directory]::Exists($copyPath) )
    { 
        $newDir = 
          [System.IO.Directory]::CreateDirectory($copyPath);
    }

    copy $filePath $copyPath;    
}

The next step is to configure the web.config according to the deployment configuration. For example, configuring the connection string for production server.

Configure web.config automatically

First, it loads the web.config in XmlDocument. This is System.Xml.XmlDocument.

$webConfigFilePath = 
  [System.IO.Path]::Combine( $deployPath, "web.config" );
if( [System.IO.File]::Exists( $webConfigFilePath ) )
{
    "    Web config found";
    [System.Xml.XmlDocument]$doc = 
       new-object System.Xml.XmlDocument;
    $doc.Load($webConfigFilePath);

Then, it changes some settings like changing the compilation mode to debug="false", which is highly recommended for the production server and sets the connection string.

$root = $doc.get_DocumentElement();

# Change compilation mode to debug="false"    
$root."system.web".compilation.debug = "false";

# Set deployment configuration specific connection string
$root.connectionStrings.add.connectionString = $CONNECTION_STRING

You can set multiple connection strings here easily. Then it runs through all <appSettings> keys, and modifies the properties according to deployment configuration:

foreach( $item in $root.appSettings.add )
{
    if( $item.key -eq "Proxy" )
    { $item.value = ""; }
    if( $item.key -eq "Version" )
    { $item.value = "" + $VERSION; }
}

The next step is to remove unwanted assemblies which should not be deployed to servers.

foreach( $item in  $root."system.web".compilation.assemblies.add )
{
    foreach( $assemblyName in $ASSEMBLIES_TO_REMOVE )
    {
        if( $item.assembly.Contains($assemblyName) )
        { 
            $removedNode = 
              $root."system.web".compilation.assemblies.RemoveChild( $item ); 
        }
    }
}

This gives us a nicely prepared web.config. I bet you have been doing all these manually before uploading some fixes to server or making new releases. See how Powershell can completely automate this and remove the possibility of human errors completely.

Update .js file names and <script> tags

The next step is to update all JavaScript references. In Pageflakes, we have a problem that when we upload modified JavaScript's, they do not get downloaded by existing users because they are cached in the client's browser. So, we need to change the file name every time we make changes to those scripts and upload on servers. This is error prone manual work. After changing the file name, we need to go to Default.aspx and change all script references and put the new file name. This is more manual work, and we generally make serious mistakes and screw up production servers at least once every three deployments. So, we completely automated this process using this Powershell script, and now we never worry about the script file problem at all.

foreach( $scriptFile in $SCRIPT_FILES )
{
    updateReferenceWithNewVersion $scriptFile 
       $DEFAULT_ASPX $VERSION $srcPath $deployPath
}

The actual work is done inside the function where we look for the file name and replace with the new name.

function updateReferenceWithNewVersion( $fileName, 
       $referenceFile, $versionNo, $srcPath, $destPath )
{
    $filePath = [System.IO.Path]::Combine( $destPath, $fileName );
    if( [System.IO.File]::Exists( $filePath ) )
    {
        "$fileName exists. Upgrading its version in $referenceFile"
        
        $referencePath = 
          [System.IO.Path]::Combine( $destPath, $referenceFile );
        if( -not [System.IO.File]::Exists( $referencePath ) )
        {
            "    Copying $referenceFile because it's not updated"
            $referenceSrcPath = 
              [System.IO.Path]::Combine( $srcPath, $referenceFile );
            $result = copy $referenceSrcPath $referencePath
        }
        
        $newFileName = $fileName.Split('.')[0] + "-" + 
             $versionNo + "." + $fileName.Split('.')[1];
        
        ren $filePath $newFileName
        
        $referenceContent = 
          [System.IO.File]::ReadAllText( $referencePath );
        $referenceContent = 
          $referenceContent.Replace( $fileName, $newFileName );
        [System.IO.File]::WriteAllText( 
          $referencePath, $referenceContent );
    }
    else
    {
        "$fileName not available"
    }
}

JSMIN all script files

We use JSMIN to compress all JavaScript files before deploying. This allows us to keep uncompressed JS files which contain lots of comments and spaces inside them without any reservation. When a script file gets deployed, JSMIN removes all comments and spaces from it, and generates a very compact version of the script which browsers understand without any problem. This reduces script download time significantly, and improves the overall site download speed.

$jsFiles = get-childitem $deployPath 
  -include *.js -Recurse | where { $_ -is [System.IO.FileInfo] }

$p = new-object System.Diagnostics.Process;
$si = new-object System.Diagnostics.ProcessStartInfo;
$si.FileName =     $jsminPath;
$si.CreateNoWindow = [Boolean]"true";

$p.StartInfo = $si;

if( $jsFiles -eq $null )
{
    "    No .js files modified"
}
foreach( $file in $jsFiles )
{
    [string]$filePath = $file.ToString();
    [string]$newFilePath = $filePath + ".new";

    $si.Arguments = "`"" + $filePath + "`" `"" + $newFilePath + "`"";

    $result = $p.Start();
    $p.WaitForExit();

    if( $result )
    {
        "    Minified: $filePath";
        copy $newFilePath $filePath;
        del $newFilePath;
    }
    else
    {
        del $newFilePath;
    }
}
$p.Dispose();

The idea is to launch jsmin.exe using the System.Diagnostics.Process class from the .NET library for each and every .js file. This looks pretty bad on screen when you have lots of .js files as one new command prompt window pops up for one second. But we don't mind it at all given the immense favor JSMIN does for us.

The attached source code with the article contains a special version of JSMIN which does not remove line breaks. We collect JavaScript errors from client side. So, we need to know the line number and the code on that line. When JSMIN removes the line number, it becomes impossible to trace the error. This is why we have modified JSMIN and prevented it from removing line breaks.

Compress HTML files

We compress all HTML files mercilessly in order to reduce their size as much as possible. Absolute HTML Optimizer is an amazing tool which does it for us. The idea is the same as JSMIN; launch ahc.exe with some command line parameters and it does the job for us.

$p = new-object System.Diagnostics.Process;

$si = new-object System.Diagnostics.ProcessStartInfo;
$si.FileName =     $htmlCompressorPath;
$si.CreateNoWindow = [Boolean]"false";
$compressorParam = "`"" + $deployPath + 
                   "`" " + $HTML_COMPRESSOR_PARAMS;
"$compressorParam"
$si.Arguments = $compressorParam;
$p.StartInfo = $si;
$result = $p.Start();
$p.WaitForExit();

if( $result )
{
    "    Compressed";
}
else
{
    "    Error occured";
}
$p.Dispose();

Zip up files using SharpZip

The deployment folder is zipped using SharpZip which is a free zip library for .NET. Here's how the DLL is loaded and initialized:

$zipLibraryPath = 
  [System.IO.Path]::GetFullPath(
  [System.IO.Path]::Combine( $pwd.ToString(), 
  "ICSharpCode.SharpZipLib.dll" ));
[void][System.Reflection.Assembly]::LoadFile($zipLibraryPath);
$zip = new-object ICSharpCode.SharpZipLib.Zip.FastZip;

Then one single line zips the files:

$zip.CreateZip( $deployZipFilePath, 
    $deployPath, [Boolean]"true", [string]::Empty );

FTP deployment package

Once we have the zip file, we use the Windows FTP command line tool to upload the zip to FTP. There's an FTP class available in .NET 2.0 System.Net. But I could not make it work properly using Powershell. So, I used the plain simple Windows FTP command line tool.

# FTP the Zip file
"Uploading file to FTP server..."
$FtpCommandFilePath = 
  [System.IO.Path]::GetFullPath(
  [System.IO.Path]::Combine( $pwd.ToString(), 
  "FTPCommand.txt" ) );
$FtpUploadCommand = "PUT `"" + $deployZipFilePath + "`"";
if( $UPLOAD_DIR.Length -gt 0 ) 
   { $FtpChdirCommand = "CD " + $UPLOAD_DIR; }
$FtpCommands = @( $USER, $PASS, 
  $FtpChdirCommand, "BINARY", $FtpUploadCommand, "QUIT" );
$FtpCommand = [String]::Join( "`r`n", $FtpCommands );
set-content $FtpCommandFilePath $FtpCommand
    
    ftp "-s:$FtpCommandFilePath" $HOSTNAME
    
    del $FtpCommandFilePath
    
    "FTP Complete." 

The idea is to build an FTP command file which contains the FTP commands like sending user name, password, and upload instructions. Then the command file is passed to ftp.exe which runs the commands and uploads the zip file.

Conclusion

Copying modified files, changing files names, configuring web.config, compressing HTML and JavaScript files, zip, FTP, all are done by one simple Powershell script. It has saved us hundreds of hours of manual labor in the last one year. It took a long time to get the script work perfectly, but the time spent on it was worth it. We can prevent any human errors during deployment, and can greatly speed up day to day patch releases on production servers using this script. Enjoy!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Omar Al Zabir
Architect BT, UK (ex British Telecom)
United Kingdom United Kingdom
Member

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionupdatesmemberkiquenet.com7 Jun '12 - 22:08 
any updates or improvements (in june 2012) about this great article ? thx
kiquenet.com

GeneralMy vote of 5memberNickos_me1 Nov '11 - 0:11 
Great article! It save my live. Thaks Smile | :)
GeneralGreat ArticlememberAbinash Bishoyi19 Jun '10 - 11:32 
Congratulation and great article, really a must read.
GeneralDowload all zip files from a ftp locationmemberpawan venugopal10 Jun '10 - 12:40 
Hi,
 
Thanks for the great artical.I was wondering if you could help me out with a power shell problem . I am trying to download all zip files from a ftp location which was added recently to a local directory but i am not able to achieve it. I can connect to the ftp but with i use get Child-Items it only allows me add local path. but it has to get child items from ftp location. Any help would be greatly appreciated.
 

 $changedFile = get-childitem "\" -Recurse | where {$_ -is [System.IO.FileInfo] -and $_.LastWriteTime -ge $LAST_CHANGE_DATETIME -and $_.extension -eq ".zip"} 

 

-Pawan
GeneralInteresting, but way out of proportion...memberzavitax9 Mar '08 - 6:22 
Looks interesting, but way too complicated in my oppinion.
Basically, what happens here, is that you use the .NET framework extensively, with yet another language which one has to learn. So where's the big advantage?
I do believe writing the same code in C# would be much more maintainable.
A C# interpreter would do much better job than this thing in terms of maintainability and understanding IMHO.
Just to make sure you get me right - I "speak" around 15 languages, some more awkward than others (including perl and several UNIX shell scripting languages), so learning a new one is always interesting for me. But from a more practical perspective - this is way out.
 
A hardworking idiot is much worse than an idiot. (C) Unknown.

GeneralExcellent, very versatile solutionmemberHolfling21 Sep '07 - 10:40 
Hi Omar,
 
Firstly, I wanted to say thanks for this. It is very useful and illustrates really well just how versatile Powershell is.
 
Although some others have said this is complex, it seems a relatively simple way of handling many different deployment procedures in one place. And, whenever the need arises, it is very easily extensible to cover pretty much anything.
 
Well done!
 

Generaldifficulty? In Understanding whymembertCodex31 May '07 - 10:04 
I agree with Alexander German - way to complex of a solution for the problem at hand. This is common for young developer's who want to impress - simple is better and easier to maintain in the long run.
 
Multiple dependencies are not necessary and make tracking down issues more complex than necessary.
 
I also saw your site. My jaw did not drop but I say you put a lot of time into emulating a linux boot up process - nice!
 
Thanks for the contribution - you certainly put a lot of time into this.
 
Hmmm | :|
 

 
TRH
GeneralRe: difficulty? In Understanding whymemberOmar Al Zabir31 May '07 - 19:57 
The complexity comes from necessity. For complex deployment scenario, it is very risky to do it by hand for multiple targets. At Pageflakes, we run a mission critical system and cannot afford to go down on deployment mistakes. We also have many staging servers and partner servers. So, there's no way a human or MSBuild script can configure the codebase and make deployment ready for different environments. So, we had to use such script. In fact the script that we use is even more complex. I just shared common scenarios.
 
But it's true, it's not necessary for small websites and definitely not for systems which does not require SLA for uptime.
 
You will see many famous products use scripting solutions for deployment. For example, Microsoft uses VBScript to pushout release on their servers. Myspace do that also. So, using scripts to prepare patches or releases is a common practice for mission critical web apps.

 
Regards,
Omar AL Zabir
Visual C# MVP

GeneralRe: difficulty? In Understanding whymember.jpg7 Jun '07 - 22:21 
IMO, writing a small custom console application is much cleaner and maintainable then the power shell solution in your example.
 
On top of that, can you explain what is a 'human script'? Aren't power shell script written by human? Finally, under what case you found msbuild can't do the job? even with custom coded task?
GeneralRe: difficulty? In Understanding why [modified]memberjrjespersen16 Aug '07 - 6:31 
I see this as difficult to maintain as well. As delivered, the tasks are not at all componentized nor optional. This is not to mention than when you are maintaining multiple web sites, if they do not all follow the exact same pattern, then you must duplicate the script and customize it for each one. It wouldn't be difficult to break the functionality apart from this script, but as is, it is not made simple.
 
It is also lacking in handling unexpected data. To truly make this better than the human inconsistency, it really needs to validate the input parameters against expected values (because a human is either going to call this script from a prompt or write the script/job that calls this one - and not necessarily the same one that writes this script). In one case, the $CONFIG variable is not handled properly - if I pass in a value other than alpha, beta, or release, the script will generate a useless connection string, but still completes the process and deploys with no message indicating a bad connection string.
 
I think a cleaner (and more generalized) PowerShell solution would have to be made before I moved away from my current process. This is especially true in cases where the same scripts are used to deploy .NET web sites as well as static HTML (or other web language) sites.
 

 

 
-- modified at 12:39 Thursday 16th August, 2007
GeneralCool stuff:)memberAsif Sayed25 May '07 - 4:47 
Cool stuffSmile | :) Keep it upSmile | :)
GeneralA few problems here...memberGreg Ennis1 Mar '07 - 18:22 
I have a few problems with this script...
 
This type of work is typically done with msbuild for a reason. What about compiling the website? What about compiling dependent projects? Are you doing this seperately and then running the script? That detracts from the 1-click idea. Also this is something msbuild is very good at, and powershell is not. So you could call msbuild from powershell but then why not just use msbuild tasks for the whole thing?
 
Putting connection strings, app settings, etc. in your build script seems like an odd choice. These settings are stored in configuration files for a reason. The code should be seperated from the data. At the very least, read in connection strings etc. from an external file. But then why not just use the "configSource" tag to begin with and forget this whole thing?
 
You compress the aspx files using Absolute HTML Compressor, however, compressing an ASPX file does little good because any server-side controls are hiding the HTML that is sent over the wire. If you were really interested in cutting down your bandwidth you need to dynamically compress the HTML after it is rendered by the server controls. I realize that pageflakes probably uses few server controls and is mostly HTML, but you posted this as a general solution on Codeproject for others to use. What are your thoughts on how to compress the rendered server control HTML?
 
Thanks

GeneralRe: A few problems here...memberOmar Al Zabir3 Mar '07 - 22:20 
Our deployment scenario is quite complicated for which we need to build different versions of the site with different configuration. That's where the powershell script helps us. We can deploy one version to Alpha server, then deploy another version to beta and then to production server 1..N. For each deployment target, we need different configuration entries in web.config. So, the powershell script helps us prepare the web.config file according to the deployment target. It also does some handy works like increasing version numbers, changing paths dynamically, deciding domain names and http url prefixes etc. I haven't showed all these here. But there are just so many things to do based on several logics in web.config that powershell was the only choice for us.
 
Regarding html compress, you are right, we are mostly .html. Although you can easily put .aspx and .ascx extension in the Absolute HTML Compressor's command line path. But there's a handy HttpModule someone in codeproject which dynamically cleans up all unnecessary whitespaces from rendered output.
 
Regards,
Omar AL Zabir
Visual C# MVP

GeneralWhy C# categorymembermicmit_syd23 Feb '07 - 14:58 
Just wondering why this article in C# category. Or since we can glue everything with PowerShell it was assigned C# category ? I was more impressed with more relevant ( as far as C# concerned ) and huge "Developing next generation Smart Clients using .NET 2.0..." comprising the whole project(s), concepts and approaches of the same author which surely deserved to be a winner but at least he was finally compensated.
 
Michael
GeneralCongratulations to Omar Al Zabirmemberazamsharp1 Feb '07 - 9:44 

I believe each and every article you write and will ever write should be automatically given article of the month or ever better article of the YEAR hmm or maybe article of the century.
 
Thank you very much Omar for taking the time to write such excellent articles. And congratulations on winning the best article. There are lots of win for you in the future Smile | :)
 
TC,
 
Azam
 
Mohammad Azam
azamsharp@gmail.com
www.gridviewguy.com
videos.gridviewguy.com
 
Houston, TEXAS

GeneralRe: Congratulations to Omar Al ZabirmemberOmar Al Zabir1 Feb '07 - 17:12 
Thank you very much!
 
Regards,
Omar AL Zabir
Visual C# MVP

GeneralcongratsmemberSamiha Esha31 Jan '07 - 22:47 
hello misho bhaia....congrats...You won it Smile | :)
 
best wishes,
samiha esha Smile | :)
 
Samiha Esha

Generalfar beyond :zzz:memberAlexander German29 Jan '07 - 11:14 
Honestly, this is not to offend, but this is far beyond from what computer science is meant to be. This is honestly too difficult to implement, I wouldnt use it, ever.
 
Alexander German

GeneralGreatmemberSajid Wasim18 Jan '07 - 4:37 
Lots of things to learn from you MishO! Keep it up buddy!
 
SAJID

QuestionPowerShell support for Win2000memberShaikh Shamshuddin25 Dec '06 - 21:36 
Hi Omar,
 
Its an excellent piece of information, surely we will benefit from it. Thanks a-lot.
 
Few of our development systems are still running on Windows 2000 Professional edition, as per my knowledge Windows PowerShell is supported by Win XP, Vista, Win 2003 (all above Win 2000).
 
Is there any alternative for using PowerShell for Windows 2000 users also?
 
Shamshuddin
AnswerRe: PowerShell support for Win2000memberOmar Al Zabir25 Dec '06 - 21:51 
Sorry I have no idea about Win 2000. May be you can ask Powershell team directly?

 
Regards,
Omar AL Zabir
Visual C# MVP

GeneralHelpfulmemberraasiel21 Dec '06 - 3:09 
Really helpful article, now I can automate a lot of stuff.
 
How about mamking this script a into a nice framework where one can inject mutiple scripts to run at various parts of the pipeline
 
"The world is not enough ...."

GeneralWe need a PowerShell topic here at Code ProjectmemberJeff Modzel19 Dec '06 - 2:27 
Good article. I've been a c# guy for a a long time (and still am) but I find myself using PowerShell more and more. Code Project could use a PowerShell topic/space.
Questionpowershell vs msbuild/nantmembernorbert_barbosa15 Dec '06 - 14:07 
Nice article,
For your knowledge, what are the pro/cons between the powershell approach and the msbuild/nant approach?
(all seems easly automaticaly callable by VS2005 or CruiseControl.Net)

AnswerRe: powershell vs msbuild/nantmemberOmar Al Zabir15 Dec '06 - 18:19 
Did not try NANT or MSBUILD yet. As far as I know, none of them has such scripting power and use .Net libraries. I do a lot of text parsing using Powershell. Also web.config configuration is important.
 
Regards,
Omar AL Zabir
Visual C# MVP

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 14 Dec 2006
Article Copyright 2006 by Omar Al Zabir
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid