Shahar Gvirtz's Weblog

IPSWeb – Web Client for Windows PowerShell

Yesterday, I published small application I developed called IPSWeb. This application is actually web client for Windows PowerShell.
It’s very simple, to install this application you create new IIS website, copy the files to the website directory and then, you have web access to the Windows PowerShell on the server.

In addition to execute commands and get the output, you can use all the great features of Windows PowerShell. There is also a built-in script editor (that will be better next versions) that gives the Server Administrator the option to create, edit and execute scripts on the server from the web client (IPSWeb), also when the ExecutionPolicy in the server doesn’t allow script execution.
IPSWeb supports more than one user in the same time, each user get his PowerShell instance. It’s also possible to create startupscript (in addition to the profile file) that will run in the beginning of each session.

The installation is very simple (full instructions available here) and take no more than two minutes.

This version (0.1) supports PowerShell v1.0 and the CTP’s of v2.0, although there aren’t any features that use the new features of PowerShell v2.0. Next versions will use the new features of v2.0, including managing of background jobs and more from the web interface.

 

This is an open-source project and v0.1 is ready. v0.1 is an alpha version so you might find some bugs. if you find any bug, please tell me about.

Download IPSWeb v0.1

 

Shahar.

How To: Prevent running ASP / ASP.NET code in specific folder

Sometimes, you may want to prevent running ASP or ASP.NET code in specific folder, for security reasons for example.
In this case, you have to follow these instructions (Windows Server 2003, IIS6):

  1. run inetmgr, the IIS management consoleimage
  2. Right-Click on the folder you want to disable ASP/ASP.NET inside
  3. Open the properties window.
  4. image In the "Directory" tab, in the "Execute Premissions list, choose "None". Now, It's impossible to execute ASP files or CGI scripts in this folder.
  5. Make an application for this folder, by clicking "Create" button.
  6. Click on the "Configuration" button.





  7. image In the "Wildcard application maps" section, choose the aspnet_isapi.dll item, and click Removee.

That's it!
Now, it's impossible to execute ASP or ASP.NET code on this folder.

Shahar.

Posted: Mar 16 2008, 02:54 PM by shahargs | with 5 comment(s)
Filed under:
PowerShell Script to backup SharePoint Site Collection

I wrote a small script that backup selected Windows SharePoint Services Site Collection and I publish it here. This is PowerShell script, that can be run manually or from scheduled task.

This is the script (you can download it, in the end of this post, if you can't see the full line):

   1:  #Backup Site Collection in Windows SharePoint Services Site Collection to file
   2:  #Author: Shahar Gvirtz
   3:  #Weblog: http://weblogs.asp.net/shahar
   4:   
   5:  param(
   6:  [string]$SiteCollectionUrl = $(throw "Please enter the URL of the Site Collection you want to backup"),
   7:  [string]$Path =$(throw "Please enter the folder you want to backup to")
   8:  )
   9:  if(test-path $path)
  10:  {
  11:      $guid = "\" + [Guid]::NewGuid().ToString()
  12:      & "$env:programfiles\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe" `
  13:   -o backup -url $SiteCollectionUrl -filename $Path$guid.backup -overwrite > $null
  14:      [DateTime]::Now.ToString() +  ": Backup Done! File name is $path$guid.backup" >> "$path\log.txt"
  15:  }
  16:  else
  17:  {
  18:      write-error "The Path doesn't exists"
  19:  }
  20:   

This script get two parameters: the first one is the Site Collection url, and the second onw is the path to the folder where you want to save the backups.
If everything works fine, this script backup your site collection using stsadm.exe command line tool (line 13 is the continue of 12. there is a Back Tick operator in the end of line 12 which means that you only break the line).
After creating the backup, the script add new line to log file, with the current time and the name of the backup file.

Here is the syntax for using this script:

c:\backup.ps1 -SiteCollectionUrl "http://web:2020" -Path c:\backups

You must give an existing folder for the path parameter!
If you use it from the task scheduler, use this syntax (change the path and the site collection url):

powershell.exe c:\script\backup.ps1 -SiteCollectionUrl "http://web:2020" -Path c:\backups

You can download the full script, as txt file from here (change the file extension from txt to ps1 before using).

Shahar Gvirtz

How-To: Use ClickOnce to deploy your Applications

Part 1 - What is ClickOnce?

CickeOnce, is a technology for deploying smart-client applications. When we talk about smart-client application that deployed with ClickOnce, we want that the application will:

  • Provide automatic installation in one click.
  • Install updated automatically
  • Can be installed from local file, or from the WEB.

ClickeOnce, give us this options out of the box, and all we need to do is to write two XML manifest files (one for the application, and one for the ClickOnce engine). If you use Visual Studio, you have a wizzard for this.
In this post, I'll show how to work with ClickOnce from Visual Studio, and from your code too.

Part 2 - How to use ClickOnce in your application?

First of all, ClickOnce supports deployment of Windows Applications from all types (Console image Applications, Windows Forms Applications, WPF Applications).
So, in this example I created a new empty Windows Forms Application. to edit the ClickOnce settings, you should go to the project properties page (by right click on the project name in the solution explorer, see pic. #1).

In the Property page go the the "Publish" tab. In this tab, you can change the ClickOnce settings for this Project. First of all, in the first textbox, you have to enter where VS will create the installation files. It can be in the local file system, web site imageand FTP.

If you'll click on the Application Files button, you can edit the files that will include in your  project.
You can add new files that are currently in your solution, and choose if they will be in the package.

 

 

image

 

In the Prerequisites screen, you can choose package that muse be installed in the computer before your project will deploy.

For example, the .NET version you use, SQL Server etc.

 

image

 

It's recommended to click on the Update button, and turn on the update feature.
By default, it's turned off. This feature give you the option to create new versions and the clients will automatically update.

By default, the updates should be in the same directory like the publish directory.
But, you can specify a special directory for the updates, if you want so. Note that the updater will check if there is a newer version in the server. the version defuned in the main screen, in the Publish tab in the Project properties. If the V in "Automatically increment revision with each publish" checked, then any publish will increase the version.

image

After you configure the Updates, click on the Options button in the main screen and configure the general details.

 

After you finish, go close this Dialog and click on the Publish button:

image

Now, Visual Studio will build your project and will publish it. After anything will done, a new IE window will open (by default, unless you change it in the Options screen.) with the product auto-generated page.image

The page that automatically generated, include the prerequisites, and if everything is already installed you can click in the "launch" link. After clicking, if you are verified publisher, the application will start automatically, and later can be started from the Start Menu shortcut.

 

 

 

Part 3 - How the updater works?

The current project includes only an empty form. Now, let's say it's version 1.0.0.1.
Now, I changed the back color of the form , and I want it to be version 2.0.0.0.

image image

I'll go to the Publish tab in the project properties and edit the version:

image

Now, I'll click the publish now button. It will publish the new version to the location I chose (in the web).
Next time I'll launch the application, as I set in the Update properties, the application will update and show this message:

image

If you click OK, then the new version will download and run.

Part 4 - ClickOnce with code

Until now, we worked with wizards and GUI to manage the ClickOnce deployment, but we can do it from our code too. First of all, we should add using statement to System.Deployment.Application:

using System.Deployment.Application;

Now, we can use the ApplicationDeployment class to manage our application deployment information. This code, for example, check for updates and shows a MessageBox with the version of the newest version for the current deployment. Note, that this code can replace the built-in message of new versions. you can cancel in the Update screen in the Publish tab the auto-check for updates, and do it manually from your code:

   1:  ApplicationDeployment deploy =   ApplicationDeployment.CurrentDeployment;
   2:  UpdateCheckInfo update = deploy.CheckForDetailedUpdate();
   3:  MessageBox.Show("You can update to version: " + update.AvailableVersion.ToString());

image

Note that this code will cause an exception if no update available, because then update.AvailableVersion.ToString() will be null. So, if you want to use this code, make sure that it's in if...else statement that show the message only if update doesn't equal to null.

We can fix this code a little, so the application will update after the message show:

ApplicationDeployment deploy = ApplicationDeployment.CurrentDeployment;
UpdateCheckInfo update = deploy.CheckForDetailedUpdate();
 if (deploy.CheckForUpdate())
{
     MessageBox.Show("You can update to version: " + update.AvailableVersion.ToString());
     deploy.Update();
     Application.Restart();
}

This code will work always. If an update is available, it will inform the user, download the update synchronously and restart the application. Otherwise, this code do nothing.

Put this code in the form load event, and then when you release a new version, the user will informed about and the application will update. you can use this code instead the built-in message, to make this progress more friendly.

Shahar Gvirtz.

Dynamic Data Web Application - Part 1

ASP.NET 3.5 Extensions is a package of new controls and tools that improve the existing ASP.NET 3.5.
One of the interesting (and time-saving) features, is the Dynamic Data Controls. Dynamic Data Controls can be used to build easily, almost without writing any line of code a complete data-driven Web Application.
The controls cover the common things that developers use when build a web application which work with DB -  view information, delete, update, view detailed information, add new data etc.

For example, let's say we need to build a management panel for DB. First, we (or the DBA) build the DB, and then, we create a web forms for managing this DB. Let see how can I do it simply with Dynamic Data Web Application in 5 minutes.

In this article, you won't see any line of code!
The site we build is actually based on the Dynamic Data controls built-in template, and doesn't include any custom logic.
In the real world, we may want to add our logic, and in the next part of the article you'll see how to do this.

Step 1 - Create a new Dynamic Data Web Applicationimage

After you downloaded and installed the ASP.NET 3.5 Extensions, you open your VS 2008, and create new Dynamic Data application. Note that you must use .NET 3.5 for this (if you use .NET 2.0, maybe you want to check ASP.NET Futures July CTP which works in .NET 2.0)

 

 

Step 2 - Add you database to the App_Data folder

In this example, I use the Northwind database.

Step 3 - Add LINQ to SQL Classes Fileimage

Add new item to your project, I called in "db". The Dynamic Data Controls based on LINQ to SQL Object Mapper, and use it to get and work with your DB. Drag from the Server Explorer the items you want that Dynamic Data will work with. I added all the tables in Northwind DB.

 

 

Step 4 - Edit your web.config file

If you don't want to customize the Dynamic Data site, and you want to create fully data driven application without writing even one line of code (great for demos), just go to web.config to line 130 and set enableTemplates property as "true" and set the dataContextType to the name of our LINQ to SQL classes name:

<dynamicData dataContextType="db" enableTemplates="true">

In this line we set Dynamic Data to work with the default templates (you can find them in App_Shared folder).

Step 5 - Run the Application

image

What we get by default?
The default template of the Dynamic Data site stored in the App_Shared folder. The web forms use the new controls - DynamicGridView (which render on client side like a standard GridView), DynamicFormView etc.

In the main page we can se list of all our tables that are in the LINQ to SQL. The LINQ to SQL include the full database schema, which means that all the relationships can be used it the Dynamic Data Site.
For example, take a look in the Products page. you see a list of all the items in GridView, you imagecan select and see details in the DetailsView in the bottom of  the page, you can sort, edit and delete.
But, you can also see that the last 3 columns, are a links to another pages that include the categories, the order dentils and the supplier information. In the database schema, this columns include only the ID of the category, the ID of the Supplier. The DynamicData Controls, show instead the ID, a link to page with the category details or the supplier details.  imageThis feature based on the LINQ to SQL that create objects from the tables, with association that make it possible for DynamicData Controls to link the relevant page instead show numeric ID.

Summary

In this part, you see how to create a simple data driven web application without write code.
In the next part, we'll see how we can customize the application. change the style, remove and add columns from the view, and add logic.

 

Shahar Gvirtz.

How to run PowerShell script from command-let

Sometimes, we want to run PowerShell script from command-let that derives from PSCmdlet (If you derived from Cmdlet, you can't use this way).
To do so, we just have to use this code:

   1:  using System.Management.Automation;
   2:  using System.Collections.ObjectModel;
   3:   
   4:  ......
   5:   
   6:  Collection<PSObject> results = InvokeCommand.InvokeScript("dir" /*replace it with your script */);
   7:  foreach (PSObject var in results)
   8:  {
   9:         WriteObject(var.ToString(),false);
  10:  }

I included in this code the important using statements, and the code itself. Few things about this code:

  1. I use PSObject as the type for the collection, which means that I can access any property and method of the returning object, include Extended methods (ETS).
  2. Always use WriteObject method in Command-lets NEVER use System.Console.
    That's because WriteObject write stream of object, not text, which is one of the biggest advantages in PowerShell - we can work with object instead text.
    When you use WriteObject you can be sure that any PowerShell host will be able to use the command-let and the output easily.

Shahar.

[Tip] Option Explicit in PowerShell

Someone asked me how we can set Windows PowerShell to work like in VB when you specify Option Explicit.
How to disable using of variables that didn't defined in the code. In this way, you know for sure that you aren't use undefined variable and get unexpected results.

to do "Option Explicit" in PowerShell, simply run this command:

set-psdebug -strict

and to disable the Option Explicit:

set-psdebug -off

Shahar.

MSDN Code Gallery

I saw it today, and it looks very cool. try the new MSDN Code Gallery.

Build API for your application based on Windows PowerShell

Windows PowerShell, is the new (kind of new) Shell from Microsoft. Actually, PowerShell is more than a shell. you can use PowerShell as a Platform. Because PowerShell commands (AKA command-lets or cmdlets) are actually .NET classes, and PowerShell, not like other shells, is object oriented, we can use powershell as a development platform.

When you write an Application, you can create a new PowerShell tier, which include command-lets which relevant for your application. for example, in student management application, I'll create the following command-lets:

  • Get-Student
  • New-Student
  • Update-Student
  • Delete-Studentimage

This PowerShell tier include command-lets that can be used as your Application API.
The command-lets you write can use by users who want to use command line for working with your application, scripts writers that can use your command lines, and you can base your GUI (PowerShell is more than command line you can create even WPF GUI PowerShell command-lets behind the scenes) based on  this command-lets (think about it: the name of command-let is verb-noun which exactly the way we describe the things the user can do with the GUI), and other applications can use this command-lets as your Application's API, because any .NET application can easily execute PowerShell scripts, include your application's command-lets, and work with the results (everything is objects).

For more information about it, download my presentation and the source code (include exampled of build GUI based on PowerShell in .NET 3.5 application [even that PowerShell command lets should be written in .NET 2.0 or be fully compatibility with it]) from my lecture about PowerShell in Developer Academy 2 (Israel).

You can also read my code project article about Build PowerShell Command-Let.

Shahar Gvirtz.

How to get the full command line

Someone asked me, and I post here the answer - sometimes, we want to get from our command-let the command that the user entered to use our command-let. we want the full line, with all the command-lets in the pipeline and all the parameters.

In this case, we will use the following code (works only from command-lets that derived from System.Management.Automation.PSCmdlet):

string commandLine = this.MyInvocation.Line;

Shahar.

Posted: Jan 24 2008, 09:36 AM by shahargs | with no comments |
Filed under: ,
More Posts Next page »