tag:blogger.com,1999:blog-62736870728306845202024-03-14T05:58:31.089+00:00The Scripting FrogCode examples for scripts in VBscript and PowerShellThe Scripting Froghttp://www.blogger.com/profile/01970287380979310232noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-6273687072830684520.post-73679700360979801802012-09-24T23:50:00.003+01:002012-09-25T18:22:39.113+01:00How to use PowerShell to search Active DirectoryPowerShell 2.0 introduced 76 new CmdLets, including Get-ADUser which allow you to query Active Directory.<br />
This was a great progress as the first release of PowerShell was miserably failing in providing a good interface with Active Directory which is unbelievable for a Microsoft product!<br />
So now, Get-ADUser and many other CmdLets are available; great! Here are the <a href="http://technet.microsoft.com/en-us/library/ee617241.aspx">details on Microsoft Website</a><br />
<br />
Hang on a minute, there is a limitation to that, you need Windows 2008 R2 domain controllers...<br />
<br />
If you can't upgrade your Windows Active Directory controllers to Windows Server 2008 R2, there is a workaround: you can install <a href="http://www.microsoft.com/en-us/download/details.aspx?id=2852">Active Directory Management Gateway Service</a> on your Windows Server 2003 or 2008 domain controllers.<br />
<br />
In the meantime, there are still options to query Active Directory using PowerShell via LDAP.<br />
<br />
The script below will show you an easy way of doing it.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">[string]$category = ""</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$name = ""</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$data = ""</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$attribute = ""</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$strFilter = "(&(objectCategory=" + $category + ")(" + $name + "=" + $data + "))"</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objDomain = New-Object System.DirectoryServices.DirectoryEntry</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objSearcher = New-Object System.DirectoryServices.DirectorySearcher</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objSearcher.SearchRoot = $objDomain</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objSearcher.PageSize = 1000</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objSearcher.Filter = $strFilter</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objSearcher.SearchScope = "Subtree"</span><br />
<span style="font-family: Courier New, Courier, monospace;">$colResults = $objSearcher.FindAll()</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">$colResults | foreach {</span><span style="font-family: 'Courier New', Courier, monospace;">$_.Properties.Item("$attribute")}</span><br />
<br />
Let's first have a look at the input variables:<br />
<br />
<ul>
<li><b>$category</b> is the category of object you're searching search in Active Directory (could be user, group, contact, groupPolicyContainer...)</li>
<li><b>$name</b> is the name of the attribute you're using as a filter to find the object (could be displayName, sAMAccountName...)</li>
<li><b>$data</b> is the value of the attibute you're using as a filter to find the object ("Joe Bloggs", ...)</li>
<li><b>$attribute</b> is the attribute's value you want to read from Active Directory for all objects matching your criteria (givenName, telephoneNumber, department)</li>
</ul>
<br />
Once the parameters in place, you create a domain object ($objDomain) where the search will be conducted (no need to mention the domain, the one in use by the computer running the script will be automatically selected)<br />
Then, you create a searcher object ($objSearcher) where you define all the settings of your search (domain where you do it, maximum number of object to return, filter to apply to your search and scope of your search)<br />
Finally, you run the search by using the FindAll() which will return a collection of objects to $colResults.<br />
The last line returns the result(s) of your search. The SearchResult collection will return objects with the Properties property which stores the data of your Active Directory objects. To read it, you just have to use the Item property with mentioning the attribute you want to read to get its value.<br />
<br />
Once, you get it right, you can wrap it up in a function like:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">function Get-AdsiData {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> [CmdletBinding()]</span><br />
<span style="font-family: Courier New, Courier, monospace;"> param (</span><br />
<span style="font-family: Courier New, Courier, monospace;"> [string]$category,</span><br />
<span style="font-family: Courier New, Courier, monospace;"> [string]$name,</span><br />
<span style="font-family: Courier New, Courier, monospace;"> [string]$data,</span><br />
<span style="font-family: Courier New, Courier, monospace;"> [string]$attribute</span><br />
<span style="font-family: Courier New, Courier, monospace;"> )</span><br />
<span style="font-family: Courier New, Courier, monospace;"> $strFilter = "(&(objectCategory=" + $category + ")(" + $name + "=" + $data + "))"</span><br />
<span style="font-family: Courier New, Courier, monospace;"> $objDomain = New-Object System.DirectoryServices.DirectoryEntry</span><br />
<span style="font-family: Courier New, Courier, monospace;"> $objSearcher = New-Object System.DirectoryServices.DirectorySearcher</span><br />
<span style="font-family: Courier New, Courier, monospace;"> $objSearcher.SearchRoot = $objDomain</span><br />
<span style="font-family: Courier New, Courier, monospace;"> $objSearcher.PageSize = 1000</span><br />
<span style="font-family: Courier New, Courier, monospace;"> $objSearcher.Filter = $strFilter</span><br />
<span style="font-family: Courier New, Courier, monospace;"> $objSearcher.SearchScope = "Subtree"</span><br />
<span style="font-family: Courier New, Courier, monospace;"> $colResults = $objSearcher.FindAll()</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">return</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">$colResults | foreach {</span><span style="font-family: 'Courier New', Courier, monospace;">$_.Properties.Item("$attribute")}</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<br />
Read more on the <a href="http://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentry.aspx">DirectoryEntry object</a> and the <a href="http://msdn.microsoft.com/en-us/library/system.directoryservices.directorysearcher.aspx">DirectorySearcher</a> and the <a href="http://msdn.microsoft.com/en-us/library/system.directoryservices.searchresult.aspx">SearchResult</a> objects...<br />
<br />
<br />The Scripting Froghttp://www.blogger.com/profile/01970287380979310232noreply@blogger.com1tag:blogger.com,1999:blog-6273687072830684520.post-91764699118474796232012-08-31T19:26:00.001+01:002012-09-06T23:00:10.633+01:00How to query a SQLite database with PowerShellRelational databases are really useful to store data and can achieve far more than flat files, so you might be interested in accessing databases with your PowerShell scripts.<br />
However, most of the relational databases applications require proper installation and quite a lot of resource.<br />
For SQLite, this is not the case; this is a "self-contained, serverless, zero-configuration, transactional SQL database engine"; it combines the best of both flat files and relational databases. For more information, please visit the website <a href="http://www.sqlite.org/">http://www.sqlite.org/</a><br />
<br />
In order for PowerShell to be able to communicate with SQLite, you need to download and install the ADO.NET adapter for SQLite: <a href="http://system.data.sqlite.org/">http://system.data.sqlite.org</a>, which includes the engine.<br />
<br />
Once installed, the following script will show you how to query a SQLite database:<br />
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">[string]$sqlite_library_path = "C:\Program Files\System.Data.SQLite\2010\bin\System.Data.SQLite.dll"</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_data_source = "C:\Temp\SQLite\MyDatabase.db"</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_query = "SELECT * FROM MyTable"</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">[void][System.Reflection.Assembly]::LoadFrom($sqlite_library_path)</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">$db_dataset = New-Object System.Data.DataSet</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;">$db_data_adapter = New-Object System.Data.SQLite.SQLiteDataAdapter($db_query,"Data Source=$db_data_source")</span><br />
<span style="font-family: Courier New, Courier, monospace;">[void]$db_data_adapter.Fill($db_dataset)</span><br />
<span style="font-family: Courier New, Courier, monospace;">$db_dataset.Tables[0]</span><br />
<br />
<br />
<br />
<br />
Let's go into details...<br />
<br />
Let's talk about the variables:<br />
First, you have to provide the location of the binary to use:<br />
<span style="font-family: Courier New, Courier, monospace;">[string]$sqlite_library_path = "C:\Program Files\System.Data.SQLite\2010\bin\System.Data.SQLite.dll"</span>
<br />
<br />
Then, you need to provide the location of your database:<br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_data_source = "C:\Temp\SQLite\MyDatabase.db"</span>
<br />
<br />
And finally, provide the SQL query you want to execute:<br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_query = "SELECT * FROM MyTable"</span>
<br />
<br />
Now, we load the SQLite library:<br />
<span style="font-family: Courier New, Courier, monospace;">[void][System.Reflection.Assembly]::LoadFrom($sqlite_library_path)</span>
<br />
<br />
You need to use a System.Data.DataSet object to store the data retrieved from the database:<br />
<span style="font-family: Courier New, Courier, monospace;">$db_dataset = New-Object System.Data.DataSet</span>
<br />
<br />
The
SQLiteDataAdapter will run the query in the $db_query variable against the database described in the "Data Source=$db_data_source" connection string.<br />
<span style="font-family: 'Courier New', Courier, monospace;">$db_data_adapter = New-Object System.Data.SQLite.SQLiteDataAdapter($db_query,"Data Source=$db_data_source")</span>
<br />
<br />
Once done, we pass the result to the DataSet using the Fill() method:<br />
<span style="font-family: Courier New, Courier, monospace;">[void]$db_data_adapter.Fill($db_dataset)</span>
<br />
([void] here is used to ignore the value the Fill() method will return)<br />
<br />
Finally, the result is displayed when reading the table from the DataSet:<br />
<span style="font-family: Courier New, Courier, monospace;">$db_dataset.Tables[0]</span>
<br />
<br />
Hope this helped...<br />
<br />
<br />The Scripting Froghttp://www.blogger.com/profile/01970287380979310232noreply@blogger.com0tag:blogger.com,1999:blog-6273687072830684520.post-42672429890907468832012-08-30T22:37:00.001+01:002012-08-31T19:26:25.114+01:00How to query a SQL database with PowershellYou can use PowerShell to read or execute query to various database like SQL, MySQL, or SQLite.<br />
<br />
The following example shows you one of the possibilities of retrieving data from a SQL database:<br />
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_server = "My_SQL_Server"</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_name = "My_Database_Name"</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_query = "My SQL Query"</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_connectionstring = "Data Source=$db_server;Database=$db_name;Integrated Security=true;"</span><br />
<span style="font-family: Courier New, Courier, monospace;">$db_data_adapter = New-Object System.Data.SqlClient.SqlDataAdapter($db_query,$
db_connectionstring )</span><br />
<span style="font-family: Courier New, Courier, monospace;">$db_dataset = New-Object System.Data.DataSet
</span><br />
<span style="font-family: Courier New, Courier, monospace;">[void]$db_data_adapter.Fill($db_dataset)</span><br />
<span style="font-family: Courier New, Courier, monospace;">$db_dataset.Tables[0]</span><br />
<br />
Let's have a look at the different steps involved in this script.<br />
<br />
First of all, you need to define your 3 parameters: location of the database, database name and your SQL query.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_server = "My_SQL_Server"</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_name = "My_Database_Name"</span><br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_query = "My SQL Query"</span><br />
<br />
Using the first two parameters, you'll be able to create your connection string:<br />
<span style="font-family: Courier New, Courier, monospace;">[string]$db_connectionstring = "Data Source=$db_server;Database=$db_name;Integrated Security=true;"</span>
<br />
<br />
<br />
Integrated Security = true means you'll use the Windows account running the script to authenticate on the database; if another type of authentication is required, look at System.Data.SqlClient.SqlCredential.<br />
<br />
You create a Data Adapter object to retrieve the data from the database mentioned in the connection string using the query (3rd parameter):<br />
<span style="font-family: Courier New, Courier, monospace;">$db_data_adapter = New-Object System.Data.SqlClient.SqlDataAdapter($db_query,$ db_connectionstring )</span>
<br />
<br />
Then, you initiate a DataSet object in order to receive the data from the Data Adapter<br />
<span style="font-family: Courier New, Courier, monospace;">$db_dataset = New-Object System.Data.DataSet</span>
<br />
<br />
You store the data from the Data Adapter to the DataSet object using the Fill method:<br />
<span style="font-family: Courier New, Courier, monospace;">[void]$db_data_adapter.Fill($db_dataset)</span>
<br />
<br />
And finally, you display the result:<br />
<span style="font-family: Courier New, Courier, monospace;">$db_dataset.Tables[0]</span>
<br />
<br />
Another option should be to use the SqlDataReader but it seems to be less efficient and also slower; it keeps the database connection opened longer than the SqlDataAdapter.<br />
<br />
Once your script gets more complicated, you might need to use the SqlConnection and SqlCommand objects to gain more control about within your script and connection, but for a simple query, this solution will do it.<br />
<br />
Hope this was helpful.The Scripting Froghttp://www.blogger.com/profile/01970287380979310232noreply@blogger.com0tag:blogger.com,1999:blog-6273687072830684520.post-75142662090951431602012-08-29T19:16:00.001+01:002012-08-29T19:16:49.011+01:00How to create a HTA like in PowershellHTML Applications (HTA) are very useful to provide a Graphical User Interface (GUI) to your VBscript, to ease its use, avoid typing mistakes and provide better output.<br />
<br />
Would it be possible to do similar thing in PowerShell?<br />
<br />
Unfortunately, Powershell does not allow you to use HTA as you can do to provide a GUI for your VBscripts.<br />
<br />
However, Powershell gives you access to .Net libraries which means that you can create a GUI using Windows Forms. Here is a example of what it looks like:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")</span><br />
<span style="font-family: Courier New, Courier, monospace;">[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">$objForm = New-Object System.Windows.Forms.Form</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objForm.Text = "My PowerShell Form"</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">$objLabel = New-Object System.Windows.Forms.Label</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objLabel.Location = New-Object System.Drawing.Size(20,20)</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objLabel.Text = "Hello World!"</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objForm.Controls.Add($objLabel)</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">$ExitButton = New-Object System.Windows.Forms.Button</span><br />
<span style="font-family: Courier New, Courier, monospace;">$ExitButton.Location = New-Object System.Drawing.Size(80,80)</span><br />
<span style="font-family: Courier New, Courier, monospace;">$ExitButton.Text = "Exit"</span><br />
<span style="font-family: Courier New, Courier, monospace;">$ExitButton.Add_Click({$objForm.Close()})</span><br />
<span style="font-family: Courier New, Courier, monospace;">$objForm.Controls.Add($ExitButton)</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">$objForm.ShowDialog()</span><br />
<br />
<br />
You can copy the code in file, save it as test.ps1 and execute the script with PowerShell; you'll see a GUI like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-5_cj6r2_-Wk/UD5cCMEId0I/AAAAAAAABYU/1S_kpsm3DD4/s1600/PowerShellWindowsForm.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-5_cj6r2_-Wk/UD5cCMEId0I/AAAAAAAABYU/1S_kpsm3DD4/s1600/PowerShellWindowsForm.jpg" /></a></div>
<br />
<br />
This is not an easy task as Windows Forms will require a lot more coding than HTA, but you can design really nice interfaces for your scripts.<br />
<br />
In order to ease the delivery of forms, without having to type hundreds of lines of code, you can use a free tool from Sapien to create the code behind the GUI called PrimalForms. You'll be able to design the GUI and it will generate the code for you. Then, all you have to do is to merge the "GUI code" into your script and link the events.<br />
<br />
To find PrimalForms Community Edition, you'll have to access the download section on Sapien website and create an account. I'm telling you: it's worth doing it, and it's free.<br />
<br />
References:<br />
<a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.aspx">System.Windows.Forms Namespace</a><br />
<a href="http://www.sapien.com/downloads">Sapien - PrimalForms Community Edition</a><br />
<br />
<br />The Scripting Froghttp://www.blogger.com/profile/01970287380979310232noreply@blogger.com0tag:blogger.com,1999:blog-6273687072830684520.post-85252195226409063052012-03-06T19:20:00.003+00:002012-03-06T21:02:05.510+00:00How to Add an Exit Function to a HTA<br />
<span style="font-family: Verdana, sans-serif;">Following my previous post about the WScript.sleep function, here is an function to add to an exit function to a HTA.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Again, using HTA is really useful to bring life to a VBScript by adding an interface. So, converting your VBScript files to a HTA is not really complicated as VBScript is native, however some functions like the </span><span style="font-family: Verdana, sans-serif;">WScript.Quit are </span><span style="font-family: Verdana, sans-serif;">not available</span><span style="font-family: Verdana, sans-serif;">.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">In a HTA, an easy way of exiting is to call the close method of the current Window object (self). Then, you have just to call the sbExitHTA sub to close the Window.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Also, if you want to get rid of the close button from the Windows title bar, add SysMenu="no" in the HTA:APPLICATION section.</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span><br />
<span style="color: #999999; font-family: 'Courier New', Courier, monospace;"><html> <br /><head> <br /><title>Simple HTA</title> <br /><HTA:APPLICATION <br /> ID="oSimpleHTA" <br /> APPLICATIONNAME="SimpleHTA" <br />><br /></head> <br /><script Language="VBScript"><br />Sub Window_Onload<br /> dataarea.innerhtml = "<p>This is a simple HTA</p>" & _<br /> "<p>Exit button: </p>" & _<br /> "<input type=""button"" value=""Exit"" onClick=""sbExitHTA"" />"<br />End Sub<br />Sub sbExitHTA<br /> Self.Close()<br />End Sub<br /></script><br /><body><br /> <h1>Simple HTA</h1> <br /> <span id="dataarea"></span><br /></body><br /></html></span><div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>The Scripting Froghttp://www.blogger.com/profile/01970287380979310232noreply@blogger.com2tag:blogger.com,1999:blog-6273687072830684520.post-74821680510852120632012-03-06T18:31:00.000+00:002012-03-06T18:35:18.929+00:00How to add a sleep function to an HTA<span style="font-family: 'Trebuchet MS', sans-serif;">The WScript.Sleep function in VBScript is useful. However, when you decide to use HTA to provide an interface to your script, the sleep function become a problem as you can't use WScript functions in HTA.</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif;"><br /></span><br />
<span style="font-family: 'Trebuchet MS', sans-serif;">For the WScript.Echo, you can use MsgBox, however, there is no equivalent for the WScript.Sleep.</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif;"><br /></span><br />
<span style="font-family: 'Trebuchet MS', sans-serif;">You could do it using a loop, that's working but it's resource intensive. You could also create a VBScript file on the fly where you include the WScript.Sleep command and run it via the HTA but there is an easier, faster and quite efficient solution. </span><br />
<span style="font-family: 'Trebuchet MS', sans-serif;">So, here is an option that I used several times which did the trick for me.</span><br />
<br />
<span style="font-family: 'Trebuchet MS', sans-serif;">In the following example, the sbWait sub is run a command line to do a ping to the localhost IP address for the number of times of your choice. Because each ping request is done every second, you just have to mention using the iSeconds variable the number of time you want to do it.</span><br />
<br />
<span style="font-family: 'Trebuchet MS', sans-serif;">Enjoy.</span><br />
<br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"><html></span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"><head></span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"><title>Simple HTA</title></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span style="color: #666666;"><HTA:APPLICATION</span></span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"> ID="oSimpleHTA"</span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"> APPLICATIONNAME="SimpleHTA"</span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;">></span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"></head></span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"><script Language="VBScript"></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span style="color: #666666;">Sub Window_Onload</span></span><br />
<span style="color: #666666;"><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">dataarea.innerhtml = "<p>This is a simple HTA</p>"</span></span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"> dataarea.innerhtml = "<p>Let's wait for 5 seconds</p>"</span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"> sbWait(5)</span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"> dataarea.innerhtml = "<p>Done.</p>"</span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;">End Sub</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span style="color: #666666;">Sub sbWait(iSeconds)</span></span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"> Dim oShell : Set oShell = CreateObject("WScript.Shell")</span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"> oShell.run "cmd /c ping localhost -n " & iSeconds,0,True</span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;">End Sub</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span style="color: #666666;"></script></span></span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"><body></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span style="color: #666666;"> <h1>Simple HTA</h1></span></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span style="color: #666666;"> <span id="dataarea"></span></span></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span style="color: #666666;"></body></span></span><br />
<span style="color: #666666; font-family: 'Courier New', Courier, monospace;"></html></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>The Scripting Froghttp://www.blogger.com/profile/01970287380979310232noreply@blogger.com3