<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>Remko Weijnen&#039;s Blog (Remko&#039;s Blog) &#187; SQL Server</title> <atom:link href="http://www.remkoweijnen.nl/blog/topics/sql-server/feed/" rel="self" type="application/rss+xml" /><link>http://www.remkoweijnen.nl/blog</link> <description>About Terminal Server, Citrix, Delphi and other stuff</description> <lastBuildDate>Tue, 31 Jan 2012 15:37:53 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.2.1</generator> <item><title>Deleting scheduled Altiris tasks from SQL</title><link>http://www.remkoweijnen.nl/blog/2011/05/03/deleting-scheduled-altiris-tasks-from-sql/</link> <comments>http://www.remkoweijnen.nl/blog/2011/05/03/deleting-scheduled-altiris-tasks-from-sql/#comments</comments> <pubDate>Tue, 03 May 2011 08:27:30 +0000</pubDate> <dc:creator>Remko</dc:creator> <category><![CDATA[SQL Server]]></category> <category><![CDATA[VMWare]]></category><guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=1731</guid> <description><![CDATA[I needed to delete around 50 scheduled tasks from several machines in Altiris because something went wrong in on of the first jobs. It would have better if the jobs were configured to fail on error and not continue but they weren&#8217;t. Deleting the jobs from the Altiris console is very, very, slow. First the [...]]]></description> <content:encoded><![CDATA[<p>I needed to delete around 50 scheduled tasks from several machines in Altiris because something went wrong in on of the first jobs.</p><p>It would have better if the jobs were configured to fail on error and not continue but they weren&#8217;t.</p><p>Deleting the jobs from the Altiris console is very, very, slow. First the console asks for confirmation (after showing the hourglass for a long time):</p><p><a  href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/05/image10.png" rel="lightbox" class="thickbox no_icon" title="image"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/05/image_thumb10.png" width="244" height="88" /></a></p><p>Then the actual delete can take a few minutes and then the next server and so on.</p><p>I decided to delete the tasks directly from SQL.</p><p>I know this is not preferred but I think in the end it&#8217;s safe enough because I found a stored procedure called <em>del_event_schedule</em> which looks like this:</p><div class="dean_ch" style="white-space: wrap;"><span class="kw1">ALTER</span> procedure <span class="br0">&#91;</span>dbo<span class="br0">&#93;</span>.<span class="br0">&#91;</span>del_event_schedule<span class="br0">&#93;</span><br /> &nbsp; &nbsp;@schedule_id &nbsp; &nbsp; &nbsp; &nbsp; int<br /> <span class="kw1">AS</span><br /> &nbsp; &nbsp;begin transaction</p><p>&nbsp; &nbsp;<span class="kw1">DELETE</span> <span class="kw1">FROM</span> event_schedule <span class="kw1">WHERE</span> schedule_id = @schedule_id</p><p>&nbsp; &nbsp;<span class="kw1">IF</span> <span class="br0">&#40;</span>@@error != <span class="nu0">0</span><span class="br0">&#41;</span><br /> &nbsp; &nbsp; &nbsp; rollback transaction<br /> &nbsp; &nbsp;else<br /> &nbsp; &nbsp; &nbsp; commit transaction</div><p>So al it does is a (transacted) delete from the table.</p><p>&#160;</p><p><span id="more-1731"></span><p>First I created a query that selects the current scheduled tasks:</p><div class="dean_ch" style="white-space: wrap;"><span class="kw1">SELECT</span> computer.name, event.name<br /> <span class="kw1">FROM</span> dbo.event_schedule <br /> <span class="kw1">INNER</span> <span class="kw1">JOIN</span> dbo.computer <span class="kw1">ON</span> dbo.computer.computer_id = dbo.event_schedule.computer_id<br /> <span class="kw1">INNER</span> <span class="kw1">JOIN</span> dbo.event <span class="kw1">ON</span> dbo.event_schedule.event_id = dbo.event.event_id<br /> <span class="kw1">WHERE</span> dbo.computer.computer_name <span class="kw1">LIKE</span> <span class="st0">&#8216;VCTXA070%&#8217;</span><br /> <span class="kw1">AND</span> dbo.event_schedule.status_code <span class="kw1">IS</span> <span class="kw1">NULL</span><br /> <span class="kw1">AND</span> event_schedule.start_time <span class="kw1">IS</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span></div><p>This selects the computer name and task name for all computers that match VCTXA070% that have not yet started (<em>status_code</em> is null).</p><p>The <em>start_time</em> check prevents deleting recurring tasks like this one:</p><p><a  href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/05/image11.png" rel="lightbox" class="thickbox no_icon" title="image"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/05/image_thumb11.png" width="400" height="40" /></a></p><p> <br />Since this gave me the correct results I deleted them:</p><div class="dean_ch" style="white-space: wrap;"><span class="kw1">DELETE</span> <span class="kw1">FROM</span> event_schedule<br /> <span class="kw1">FROM</span> dbo.event_schedule <br /> <span class="kw1">INNER</span> <span class="kw1">JOIN</span> dbo.computer <span class="kw1">ON</span> dbo.computer.computer_id = dbo.event_schedule.computer_id<br /> <span class="kw1">INNER</span> <span class="kw1">JOIN</span> dbo.event <span class="kw1">ON</span> dbo.event_schedule.event_id = dbo.event.event_id<br /> <span class="kw1">WHERE</span> dbo.computer.computer_name <span class="kw1">LIKE</span> <span class="st0">&#8216;VCTXA070%&#8217;</span><br /> <span class="kw1">AND</span> dbo.event_schedule.status_code <span class="kw1">IS</span> <span class="kw1">NULL</span><br /> <span class="kw1">AND</span> event_schedule.start_time <span class="kw1">IS</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span></div><p>If you want to delete completed tasks as well you can just leave out the <em>status_code</em> check:</p><div class="dean_ch" style="white-space: wrap;"><span class="kw1">DELETE</span> <span class="kw1">FROM</span> event_schedule<br /> <span class="kw1">FROM</span> dbo.event_schedule <br /> <span class="kw1">INNER</span> <span class="kw1">JOIN</span> dbo.computer <span class="kw1">ON</span> dbo.computer.computer_id = dbo.event_schedule.computer_id<br /> <span class="kw1">INNER</span> <span class="kw1">JOIN</span> dbo.event <span class="kw1">ON</span> dbo.event_schedule.event_id = dbo.event.event_id<br /> <span class="kw1">WHERE</span> dbo.computer.computer_name <span class="kw1">LIKE</span> <span class="st0">&#8216;VCTXA070%&#8217;</span><br /> <span class="kw1">AND</span> event_schedule.start_time <span class="kw1">IS</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span></div> ]]></content:encoded> <wfw:commentRss>http://www.remkoweijnen.nl/blog/2011/05/03/deleting-scheduled-altiris-tasks-from-sql/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Apply IP Configuration from a Database</title><link>http://www.remkoweijnen.nl/blog/2011/04/29/apply-ip-configuration-from-a-database/</link> <comments>http://www.remkoweijnen.nl/blog/2011/04/29/apply-ip-configuration-from-a-database/#comments</comments> <pubDate>Fri, 29 Apr 2011 08:27:27 +0000</pubDate> <dc:creator>Remko</dc:creator> <category><![CDATA[Altiris]]></category> <category><![CDATA[script]]></category> <category><![CDATA[SQL Server]]></category><guid isPermaLink="false">http://www.remkoweijnen.nl/blog/2011/04/29/apply-ip-configuration-from-a-database/</guid> <description><![CDATA[I am currently deploying 64 Citrix XenApp servers with Altiris. The deployment consists of an OS Image, OS Configuration and finally Citrix XenApp and Applications. In the OS Configuration part the IP configuration needs to be applied and I decided to do this with a database. The database consists of 2 tables; one table with [...]]]></description> <content:encoded><![CDATA[<p>I am currently deploying 64 Citrix XenApp servers with Altiris. The deployment consists of an OS Image, OS Configuration and finally Citrix XenApp and Applications.</p><p>In the OS Configuration part the IP configuration needs to be applied and I decided to do this with a database.</p><p>The database consists of 2 tables; one table with the per host settings and one table with the global settings (such as DNS).</p><p>In the Altiris job both tables are read from an embedded VBScript and assigned to the NIC.</p><p><span style="text-decoration: underline;"><strong>Database configuration</strong></span></p><p>I created a database (SQL Server) called IPManagement with 2 tables:</p><p><a  rel="lightbox" href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image7.png" class="thickbox no_icon" title="image"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image_thumb7.png" border="0" alt="image" width="177" height="100" /></a></p><p>&nbsp;</p><p><span id="more-1695"></span></p><p>The globalconfig table has a name and a data field:</p><p><a  rel="lightbox" href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image8.png" class="thickbox no_icon" title="image"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image_thumb8.png" border="0" alt="image" width="244" height="74" /></a></p><p>And contains only the DNS settings:</p><p><a  rel="lightbox" href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image9.png" class="thickbox no_icon" title="image"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image_thumb9.png" border="0" alt="image" width="144" height="60" /></a></p><p>The hostconfig table has fields for hostname, ip address, netmask and default gateway:</p><p><a  rel="lightbox" href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image10.png" class="thickbox no_icon" title="image"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image_thumb10.png" border="0" alt="image" width="244" height="88" /></a></p><p>Some sample data:</p><p><a  rel="lightbox" href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image11.png" class="thickbox no_icon" title="image"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image_thumb11.png" border="0" alt="image" width="244" height="211" /></a></p><p><strong><span style="text-decoration: underline;"> </span></strong></p><p><strong><span style="text-decoration: underline;">Altiris Configuration</span></strong></p><p>In Altiris I have added the database as a custom data source, this can be done via Tools | Options | Custom Data Sources:</p><p><a  rel="lightbox" href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image12.png" class="thickbox no_icon" title="image"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image_thumb12.png" border="0" alt="image" width="244" height="238" /></a></p><p><a  rel="lightbox" href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image13.png" class="thickbox no_icon" title="image"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2011/04/image_thumb13.png" border="0" alt="image" width="244" height="197" /></a></p><p><strong><span style="text-decoration: underline;"> </span></strong></p><p><strong><span style="text-decoration: underline;">The Script:</span></strong></p><p>The final step is the VBScript, which use the <a  href="http://www.myitforum.com/articles/5/view.asp?id=5439" target="_blank">Custom Token feature</a> to retreive the data from the database:</p><div class="dean_ch" style="white-space: wrap;"><span class="co1">&#8216;Set Network Configuration</span><br /> <span class="co1">&#8216;vbscript</span><br /> IPAddress=<span class="kw1">Array</span><span class="br0">&#40;</span><span class="kw1">Trim</span><span class="br0">&#40;</span><span class="st0">&quot; %#IPManagement*&quot;</span>select ip from hostconfig where hostname=<span class="co1">&#8216;%NODEFULL%&#8217;&quot;% &quot;))</span><br /> NetMask=<span class="kw1">Array</span><span class="br0">&#40;</span><span class="kw1">Trim</span><span class="br0">&#40;</span><span class="st0">&quot; %#IPManagement*&quot;</span>select mask from hostconfig where hostname=<span class="co1">&#8216;%NODEFULL%&#8217;&quot;% &quot;))</span><br /> Gateway=<span class="kw1">Array</span><span class="br0">&#40;</span><span class="kw1">Trim</span><span class="br0">&#40;</span><span class="st0">&quot; %#IPManagement*&quot;</span>select gateway from hostconfig where hostname=<span class="co1">&#8216;%NODEFULL%&#8217;&quot;% &quot;))</span><br /> DNS=<span class="kw1">Array</span><span class="br0">&#40;</span><span class="kw1">Trim</span><span class="br0">&#40;</span><span class="st0">&quot; %#IPManagement*&quot;</span>select data from globalconfig where <span class="kw1">name</span>=<span class="co1">&#8216;dns1&#8242;&quot;% &quot;), Trim(&quot; %#IPManagement*&quot;select data from globalconfig where name=&#8217;dns2&#8242;&quot;% &quot;))</span></p><p>Metric = <span class="kw1">Array</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span></p><p>strComputer = <span class="st0">&quot;.&quot;</span><br /> <span class="kw1">Set</span> objWMIService = <span class="kw1">GetObject</span><span class="br0">&#40;</span><span class="st0">&quot;winmgmts:\\&quot;</span> &amp; strComputer &amp; <span class="st0">&quot;\root\cimv2&quot;</span><span class="br0">&#41;</span><br /> <span class="kw1">Set</span> colItems = objWMIService.<span class="me1">ExecQuery</span><span class="br0">&#40;</span><span class="st0">&quot;Select * from Win32_NetworkAdapterConfiguration where IPEnabled = True&quot;</span>,,<span class="nu0">48</span><span class="br0">&#41;</span></p><p><span class="kw1">For</span> Each objItem in colItems</p><p>&nbsp; &nbsp;<span class="kw1">If</span> <span class="kw1">Left</span><span class="br0">&#40;</span>objItem.<span class="me1">IPAddress</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span>, <span class="nu0">6</span><span class="br0">&#41;</span> = <span class="st0">&quot;10.250&quot;</span> <span class="kw1">Then</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;WScript.<span class="me1">Echo</span><span class="br0">&#40;</span><span class="st0">&quot;Found Adapter, current adres is: &quot;</span> &amp;amp; objItem.<span class="me1">IPAddress</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span> &amp;amp; <span class="st0">&quot; Desired Address is: &quot;</span> &amp; IPAddress<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;Ret = objItem.<span class="me1">EnableStatic</span><span class="br0">&#40;</span>IPAddress, NetMask<span class="br0">&#41;</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;WScript.<span class="me1">Echo</span><span class="br0">&#40;</span><span class="st0">&quot;EnableStatic returned: &quot;</span> &amp; Ret<span class="br0">&#41;</span></p><p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">If</span> Ret = <span class="nu0">0</span> <span class="kw1">Then</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;Ret = objItem.<span class="me1">SetGateWays</span><span class="br0">&#40;</span>Gateway, Metric<span class="br0">&#41;</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;WScript.<span class="me1">Echo</span><span class="br0">&#40;</span><span class="st0">&quot;SetGateWays returned: &quot;</span> &amp; Ret<span class="br0">&#41;</span>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;</p><p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;Ret = objItem.<span class="me1">SetDNSServerSearchOrder</span><span class="br0">&#40;</span>DNS<span class="br0">&#41;</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;WScript.<span class="me1">Echo</span><span class="br0">&#40;</span><span class="st0">&quot;SetDNSServerSearchOrder returned: &quot;</span> &amp; Ret<span class="br0">&#41;</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">End</span> <span class="kw1">If</span></p><p>&nbsp; &nbsp;<span class="kw1">End</span> <span class="kw1">If</span><br /> <span class="kw1">Next</span></p><p>WScript.<span class="me1">Quit</span><span class="br0">&#40;</span>Ret<span class="br0">&#41;</span></div><p>Note that I had to do a little trick using the Trim statement and a space to get a correct assignment to the variables. Without the space Altiris doesn&#8217;t properly recognize the custom token.</p><p>The array is necessary beasue the EnableStatic and SetGateways Methods require array parameters even when there&#8217;s just a single entry.</p> ]]></content:encoded> <wfw:commentRss>http://www.remkoweijnen.nl/blog/2011/04/29/apply-ip-configuration-from-a-database/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>SQL Query to get the Full Path of an Altiris Job #3</title><link>http://www.remkoweijnen.nl/blog/2010/12/12/sql-query-to-get-the-full-path-of-an-altiris-job-3/</link> <comments>http://www.remkoweijnen.nl/blog/2010/12/12/sql-query-to-get-the-full-path-of-an-altiris-job-3/#comments</comments> <pubDate>Sun, 12 Dec 2010 18:50:32 +0000</pubDate> <dc:creator>Remko</dc:creator> <category><![CDATA[Altiris]]></category> <category><![CDATA[SQL Server]]></category><guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=845</guid> <description><![CDATA[Last time I showed a User Defined Function to the Full Path of an Altiris Job given it&#8217;s id (event_id). Note that Altiris calls a Job an Event so the terms Event and Jobs are interchangeable here. To complete it we first need to prepend the server and share name to the path. I looked [...]]]></description> <content:encoded><![CDATA[<p>Last time I <a  title="SQL Query to get the Full Path of an Altiris Job #2" href="http://www.remkoweijnen.nl/blog/2010/12/09/sql-query-to-get-the-full-path-of-an-altiris-job-2/" target="_blank">showed</a> a User Defined Function to the Full Path of an Altiris Job given it&#8217;s id (event_id). Note that Altiris calls a Job an Event so the terms Event and Jobs are interchangeable here.</p><p>To complete it we first need to prepend the server and share name to the path.</p><p>I looked into the Altiris database tables to find the best place to get the servername and it seems that the hostname column of the mmsettings table is a good way.</p><p>In my database there was only one row in the table but I restrict the results by adding top 1:</p><div class="dean_ch" style="white-space: wrap;"><span class="kw1">SELECT</span> TOP <span class="nu0">1</span> hostname <span class="kw1">FROM</span> mmsettings</div><p>Then I looked into the available tokens for one that returns a job id but we can only return a job name or a computer id. Since a job name is not unique I decided to use the computername and find the active job for this computer.</p><p>When a Job is scheduled an entry is added to the event_schedule table. If you look into this table you will notice a column status_code which is NULL initially and when the job start it will get a value of -1 which indicates the job is active.</p><p>When the job has finished the status will always be 0 or higher.<span id="more-845"></span>So we can determine the active job by querying the event_schedule table for the computer_id and status_code = -1.</p><div class="dean_ch" style="white-space: wrap;">DECLARE @EventId int<br /> <span class="kw1">SELECT</span> @EventId = event_id<br /> <span class="kw1">FROM</span> event_schedule<br /> <span class="kw1">WHERE</span> computer_id = @ComputerId<br /> <span class="kw1">AND</span> status_code = <span class="nu0">-1</span></div><p>But I found out that during the phase where the Custom Tokens are evaluated the status_code column is still NULL.</p><p>However if we query for status_code is NULL we may get back more than one row if there a several jobs scheduled for this computer. So again I used the TOP 1 statement to limit the results:</p><div class="dean_ch" style="white-space: wrap;">DECLARE @EventId int<br /> <span class="kw1">SELECT</span> TOP <span class="nu0">1</span> @EventId = event_id<br /> <span class="kw1">FROM</span> event_schedule<br /> <span class="kw1">WHERE</span> computer_id = @ComputerId<br /> <span class="kw1">AND</span> status_code <span class="kw1">IS</span> <span class="kw1">NULL</span></div><p>This is the final UDF:</p><div class="dean_ch" style="white-space: wrap;"><span class="kw1">CREATE</span> <span class="kw1">FUNCTION</span> <span class="br0">&#91;</span>dbo<span class="br0">&#93;</span>.<span class="br0">&#91;</span>GetActiveFullPath<span class="br0">&#93;</span><br /> &nbsp; <span class="br0">&#40;</span> @ComputerId int<span class="br0">&#41;</span><br /> RETURNS nvarchar<span class="br0">&#40;</span><span class="nu0">4000</span><span class="br0">&#41;</span><br /> <span class="kw1">AS</span><br /> BEGIN<br /> &nbsp; &nbsp;DECLARE @EventId int<br /> &nbsp; &nbsp;<span class="kw1">SELECT</span> TOP <span class="nu0">1</span> @EventId = event_id<br /> &nbsp; &nbsp;<span class="kw1">FROM</span> event_schedule<br /> &nbsp; &nbsp;<span class="kw1">WHERE</span> computer_id = @ComputerId<br /> &nbsp; &nbsp;<span class="kw1">AND</span> status_code <span class="kw1">IS</span> <span class="kw1">NULL</span></p><p>&nbsp; &nbsp;DECLARE @str nvarchar<span class="br0">&#40;</span><span class="nu0">4000</span><span class="br0">&#41;</span>;<br /> &nbsp; &nbsp;<span class="kw1">WITH</span> t1 <span class="br0">&#40;</span>folder_id, name, parent_id, level<span class="br0">&#41;</span><br /> &nbsp; &nbsp;<span class="kw1">AS</span><br /> &nbsp; &nbsp;<span class="br0">&#40;</span><br /> &nbsp; &nbsp;<span class="co1">&#8211; Anchor member definition</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">SELECT</span> folder_id, name, parent_id, <span class="nu0">0</span> <span class="kw1">AS</span> Level<br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">FROM</span> event_folder<br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">WHERE</span> folder_id <span class="kw1">IN</span> <span class="br0">&#40;</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">SELECT</span> folder_id <span class="kw1">FROM</span> event <span class="kw1">WHERE</span> event_id = @EventId<span class="br0">&#41;</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;UNION <span class="kw1">ALL</span></p><p>&nbsp; &nbsp;<span class="co1">&#8211; Recursive member definition</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">SELECT</span> t2.folder_id,t2.name, t2.parent_id, Level<span class="nu0">+1</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">FROM</span> event_folder <span class="kw1">AS</span> t2, t1<br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">WHERE</span> t2.folder_id = t1.parent_id<br /> &nbsp; &nbsp;<span class="br0">&#41;</span></p><p>&nbsp; &nbsp;<span class="co1">&#8211; Statement that executes the CTE</span><br /> &nbsp; &nbsp;<span class="co1">&#8211; STUFF and FOR XML are used to Concatenate the Values and seperate them by \ character</span></p><p>&nbsp; &nbsp;<span class="kw1">SELECT</span> @str = STUFF<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw1">SELECT</span> <span class="st0">&#8216;<span class="es0">\&#8217;</span> + name from t1 order by level desc FOR XML PATH(&#8216;</span><span class="st0">&#8216;)),1,1,&#8217;</span><span class="st0">&#8216;)</p><p>&nbsp; &nbsp;&#8211; Prepend Servername and Share<br /> &nbsp; &nbsp;SET @str = &#8216;</span>\\<span class="st0">&#8216; + (SELECT TOP 1 hostname FROM mmsettings) + &#8216;</span>\eXpress\<span class="st0">&#8216; + @str<br /> &nbsp; &nbsp;RETURN @str;<br /> END</span></div><p>And we use it like this in the Job:</p><div class="dean_ch" style="white-space: wrap;">set JOBFOLDER=%#*&quot;SELECT dbo.GetActiveFullPath(%ID%)&quot;%<br /> if not exist %JOBFOLDER% MD %JOBFOLDER%</div><p>I didn&#8217;t find the share name in any of the tables so I hardcoded it as eXpress. If there&#8217;s a better way please let me know!</p><p>I would be very interested in your comments, do you find this approach usefull or do you have suggestions? Please leave a comment!</p> ]]></content:encoded> <wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/12/12/sql-query-to-get-the-full-path-of-an-altiris-job-3/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>SQL Query to get the Full Path of an Altiris Job #2</title><link>http://www.remkoweijnen.nl/blog/2010/12/09/sql-query-to-get-the-full-path-of-an-altiris-job-2/</link> <comments>http://www.remkoweijnen.nl/blog/2010/12/09/sql-query-to-get-the-full-path-of-an-altiris-job-2/#comments</comments> <pubDate>Thu, 09 Dec 2010 09:00:43 +0000</pubDate> <dc:creator>Remko</dc:creator> <category><![CDATA[Altiris]]></category> <category><![CDATA[SQL Server]]></category><guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=840</guid> <description><![CDATA[Earlier I described a SQL Query to get the Full Path of an Altiris Job, today I will describe how we can make a User Defined Function (UDF) in SQL so we can call it easier. I am using an UDF because it allows us to specify parameters, in this case a single parameter (the [...]]]></description> <content:encoded><![CDATA[<p>Earlier I described a <a  href="http://www.remkoweijnen.nl/blog/2010/12/07/sql-query-to-get-the-full-path-of-an-altiris-job/">SQL Query to get the Full Path of an Altiris Job</a>, today I will describe how we can make a <a  title="User Defined Functions" href="http://msdn.microsoft.com/en-us/library/ms189593.aspx" target="_blank">User Defined Function</a> (UDF) in SQL so we can call it easier.</p><p>I am using an UDF because it allows us to specify parameters, in this case a single parameter (the EventId (or job id).</p><p>This is the SQL that creates the UDF:</p><div class="dean_ch" style="white-space: wrap;"><span class="kw1">CREATE</span> <span class="kw1">FUNCTION</span> GetFullPath<br /> &nbsp; <span class="br0">&#40;</span> @EventId int<span class="br0">&#41;</span><br /> RETURNS nvarchar<span class="br0">&#40;</span><span class="nu0">4000</span><span class="br0">&#41;</span><br /> <span class="kw1">AS</span><br /> BEGIN<br /> &nbsp; &nbsp;DECLARE @str nvarchar<span class="br0">&#40;</span><span class="nu0">4000</span><span class="br0">&#41;</span>;<br /> &nbsp; &nbsp;<span class="kw1">WITH</span> t1 <span class="br0">&#40;</span>folder_id, name, parent_id, level<span class="br0">&#41;</span><br /> &nbsp; &nbsp;<span class="kw1">AS</span><br /> &nbsp; &nbsp;<span class="br0">&#40;</span><br /> &nbsp; &nbsp;<span class="co1">&#8211; Anchor member definition</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">SELECT</span> folder_id, name, parent_id, <span class="nu0">0</span> <span class="kw1">AS</span> Level<br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">FROM</span> event_folder<br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">WHERE</span> folder_id <span class="kw1">IN</span> <span class="br0">&#40;</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">SELECT</span> folder_id <span class="kw1">FROM</span> event <span class="kw1">WHERE</span> event_id = @EventId<span class="br0">&#41;</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;UNION <span class="kw1">ALL</span></p><p>&nbsp; &nbsp;<span class="co1">&#8211; Recursive member definition</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">SELECT</span> t2.folder_id,t2.name, t2.parent_id, Level<span class="nu0">+1</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">FROM</span> event_folder <span class="kw1">AS</span> t2, t1<br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">WHERE</span> t2.folder_id = t1.parent_id<br /> &nbsp; &nbsp;<span class="br0">&#41;</span></p><p>&nbsp; &nbsp;<span class="co1">&#8211; Statement that executes the CTE</span><br /> &nbsp; &nbsp;<span class="co1">&#8211; STUFF and FOR XML are used to Concatenate the Values and seperate them by \ character</span></p><p>&nbsp; &nbsp;<span class="kw1">SELECT</span> @str = STUFF<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw1">SELECT</span> <span class="st0">&#8216;<span class="es0">\&#8217;</span> + name from t1 order by level desc FOR XML PATH(&#8216;</span><span class="st0">&#8216;)),1,1,&#8217;</span><span class="st0">&#8216;)<br /> &nbsp; &nbsp;RETURN @str<br /> END<br /> GO</span></div><p><span id="more-840"></span>After you have executed this, you can find the UDF in the Programmability Section of SQL:</p><p><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/12/sqlprogsection.png" alt="SqlProgSection" width="296" height="241" /></p><p>To call this UDF you need to use the two part name (dbo.GetFullPath) as described <a  title="Executing User-Defined Functions" href="http://msdn.microsoft.com/en-us/library/ms175562.aspx" target="_blank">here</a>.</p><p>Example:</p><p><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/12/udfcallexample.png" alt="UdfCallExample" width="375" height="264" /></p><p>Next step will be to prepend the <a href="file://\\SERVER\Share">\\SERVER\Share</a> part which we can do in the UDF as well.</p> ]]></content:encoded> <wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/12/09/sql-query-to-get-the-full-path-of-an-altiris-job-2/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>SQL Query to get the Full Path of an Altiris Job</title><link>http://www.remkoweijnen.nl/blog/2010/12/07/sql-query-to-get-the-full-path-of-an-altiris-job/</link> <comments>http://www.remkoweijnen.nl/blog/2010/12/07/sql-query-to-get-the-full-path-of-an-altiris-job/#comments</comments> <pubDate>Tue, 07 Dec 2010 21:22:56 +0000</pubDate> <dc:creator>Remko</dc:creator> <category><![CDATA[Altiris]]></category> <category><![CDATA[SQL Server]]></category><guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=831</guid> <description><![CDATA[I wanted to query the full path name of an Altiris Job, this sounds easier that it is though. Consider the following hierarchy: Now I want to assemble the full Path, in this case: RPA\Getronics\PKG_p007.Citrix_Components. This is important because I want to automatically create the corresponding directory structure which would be: \\SERVER\eXpress\RPA\Getronics\PKG_p007.Citrix_Components. Altiris stores the [...]]]></description> <content:encoded><![CDATA[<p>I wanted to query the full path name of an Altiris Job, this sounds easier that it is though.</p><p>Consider the following hierarchy:</p><p><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/12/tree1.png" alt="Tree" width="302" height="360" /></p><p>Now I want to assemble the full Path, in this case: RPA\Getronics\PKG_p007.Citrix_Components.</p><p><span id="more-831"></span>This is important because I want to automatically create the corresponding directory structure which would be: \\SERVER\eXpress\RPA\Getronics\PKG_p007.Citrix_Components.</p><p>Altiris stores the Job (04.DeliveryServicesConsole) in the events table and in this table is a column folder_id. We can then lookup this folder_id in the event_folder table where each folder_id has a parent_id (which can be null in case of a root folder).</p><p>So we need to traverse the tree from the bottom up until we find the root folder. SQL Server has a mechanism for recursive queries called <a  href="http://msdn.microsoft.com/en-us/library/ms186243.aspx">Common Table Expressions</a>.</p><p>Using this mechanism I made the following query: </p><div class="dean_ch" style="white-space: wrap;"><span class="kw1">WITH</span> t1 <span class="br0">&#40;</span>folder_id, name, parent_id, level<span class="br0">&#41;</span><br /> <span class="kw1">AS</span><br /> <span class="br0">&#40;</span><br /> <span class="co1">&#8211; Anchor member definition</span><br /> &nbsp; &nbsp;<span class="kw1">SELECT</span> folder_id, name, parent_id, <span class="nu0">0</span> <span class="kw1">AS</span> Level<br /> &nbsp; &nbsp;<span class="kw1">FROM</span> event_folder<br /> &nbsp; &nbsp;<span class="kw1">WHERE</span> folder_id <span class="kw1">IN</span> <span class="br0">&#40;</span><br /> &nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">SELECT</span> folder_id <span class="kw1">FROM</span> event <span class="kw1">WHERE</span> event_id = <span class="nu0">2000112</span><span class="br0">&#41;</span><br /> &nbsp; &nbsp;UNION <span class="kw1">ALL</span></p><p><span class="co1">&#8211; Recursive member definition</span><br /> &nbsp; &nbsp;<span class="kw1">SELECT</span> t2.folder_id,t2.name, t2.parent_id, Level<span class="nu0">+1</span><br /> &nbsp; &nbsp;<span class="kw1">FROM</span> event_folder <span class="kw1">AS</span> t2, t1<br /> &nbsp; &nbsp;<span class="kw1">WHERE</span> t2.folder_id = t1.parent_id<br /> <span class="br0">&#41;</span></p><p><span class="co1">&#8211; Statement that executes the CTE</span><br /> <span class="co1">&#8211; STUFF and FOR XML are used to Concatenate the Values and seperate them by \ character</span><br /> <span class="kw1">SELECT</span> STUFF<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw1">SELECT</span> <span class="st0">&#8216;<span class="es0">\&#8217;</span> + name from t1 order by level desc FOR XML PATH(&#8216;</span><span class="st0">&#8216;)),1,1,&#8217;</span><span class="st0">&#8216;)</span></div><p>The output is: RPA\Getronics\PKG_\p007.Citrix_Components</p><p>I added the Level column to be able to sort on it (descending) to get the proper path order, else it would have been  p007.Citrix_Components\PKG_\Getronics\RPA.</p><p>Next steps are to prepend the \\SERVER\eXpress part and make the query parameterised so I can call it from within a job using the %JOBID% token.</p><p>To be continued&#8230;</p> ]]></content:encoded> <wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/12/07/sql-query-to-get-the-full-path-of-an-altiris-job/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Altiris AxSched ignores the DSN parameter</title><link>http://www.remkoweijnen.nl/blog/2010/11/23/altiris-axsched-ignores-the-dsn-parameter/</link> <comments>http://www.remkoweijnen.nl/blog/2010/11/23/altiris-axsched-ignores-the-dsn-parameter/#comments</comments> <pubDate>Tue, 23 Nov 2010 21:48:47 +0000</pubDate> <dc:creator>Remko</dc:creator> <category><![CDATA[Altiris]]></category> <category><![CDATA[SQL Server]]></category><guid isPermaLink="false">http://www.remkoweijnen.nl/blog/2010/11/23/altiris-axsched-ignores-the-dsn-parameter/</guid> <description><![CDATA[I was playing around with the AxSched tool that comes with Altiris, in my case the version that comes with v6.9 build 453. I could not make it connect to the Deployment Server from my test machine, it seemed like the /dsn parameter I used was totally ignored. I also tried the /d and /db [...]]]></description> <content:encoded><![CDATA[<p>I was playing around with the AxSched tool that comes with Altiris, in my case the version that comes with v6.9 build 453.</p><p>I could not make it connect to the Deployment Server from my test machine, it seemed like the /dsn parameter I used was totally ignored.</p><p>I also tried the /d and /db parameters but they didn&#8217;t have any effect at all, the message was always:</p><blockquote><p>Error opening database connection:<br /> SQL Server does not exist or access denied.<br /> ConnectionOpen (Connect()).</p></blockquote><p>So I opened AxSched in Ida Pro and set a Breakpoint to the place where the SQL Connection seems to be made:</p><p><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/sqldriverconnect.png" alt="SQLDriverConnect" width="365" height="309" /></p><p>Ida nicely hints us that the ConnectionString is in the ECX register so we only have to inspect it to see it&#8217;s value.</p><p>Actually AxSched does several attemps and the used Connection Strings are:</p><ol><li>DRIVER={SQL Server};DSN=;SERVER=;Trusted_Connection=yes;</li><li>DRIVER={SQL Server};DSN=;SERVER=;UID=sa;PWD=;Trusted_Connection=no;</li><li>DSN=Altiris eXpress Database;</li><li>DSN=Altiris eXpress Database;Trusted_Connection=yes;</li><li>DSN=Altiris eXpress Database;UID=sa;PWD=;Trusted_Connection=no;</li></ol><p>So I bypassed by adding a DSN with the name Altiris eXpress Database and then it works.</p> ]]></content:encoded> <wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/11/23/altiris-axsched-ignores-the-dsn-parameter/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Why is my scheduled job not executed in Altiris?</title><link>http://www.remkoweijnen.nl/blog/2010/11/23/why-is-my-scheduled-job-not-executed-in-altiris/</link> <comments>http://www.remkoweijnen.nl/blog/2010/11/23/why-is-my-scheduled-job-not-executed-in-altiris/#comments</comments> <pubDate>Tue, 23 Nov 2010 19:34:15 +0000</pubDate> <dc:creator>Remko</dc:creator> <category><![CDATA[Altiris]]></category> <category><![CDATA[SQL Server]]></category><guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=799</guid> <description><![CDATA[Earlier today I wrote about my Altiris Job Builder tool but when I tested the actual produced build job I noticed something weird: the job was scheduled but not executed. I then tried to manually push a job to this server and that one executed fine. When I clicked the Job I could see that [...]]]></description> <content:encoded><![CDATA[<p>Earlier today I wrote about my <a  href="http://www.remkoweijnen.nl/blog/2010/11/23/altiris-job-builder/">Altiris Job Builder</a> tool but when I tested the actual produced build job I noticed something weird: the job was scheduled but not executed.</p><p>I then tried to manually push a job to this server and that one executed fine.</p><p>When I clicked the Job I could see that it was scheduled:</p><p><a  href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/job1.png" class="thickbox no_icon" rel="gallery-799" title="Job1"><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/job1-small.png" alt="Job1" width="430" height="246" /></a></p><p>But when I clicked the Server it wasn&#8217;t there:</p><p><a  href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/job2.png" class="thickbox no_icon" rel="gallery-799" title="Job2"><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/job2-small.png" alt="Job2" width="430" height="313" /></a></p><p><span id="more-799"></span>Then I fired up SQL Server Management Studio and made a query on the computer table:</p><p><a  href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/computertable.png" class="thickbox no_icon" rel="gallery-799" title="ComputerTable"><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/computertable-small.png" alt="ComputerTable" width="430" height="374" /></a></p><p>Interesting results no? At least it&#8217;s clear what happens, AxSched schedules the job for <em>the first computer that matches the given computername</em>.</p><p>And in this case the computer is longer present in the console (it&#8217;s group_id is NULL). I assume this happened because I redeployed the Virtual Machine.</p><p>So we can fix the error by issueing a SQL Statement, let&#8217;s check first:</p><p><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/sqlcheck.png" alt="SQLCheck" width="415" height="339" /></p><p>Yep, that query is ok, so we can delete it.<br /> <strong>CAUTION: BEFORE YOU CONTINUE MAKE A BACKUP OF THE DATABASE</strong></p><blockquote><p>DELETE FROM computer WHERE name = &#8216;cxnrd02&#8242; AND group_id IS NULL</p></blockquote><p>or to clean all:</p><blockquote><p>DELETE FROM computer WHERE group_id IS NULL</p></blockquote><p>My assumption was right, this fixed the problem!</p> ]]></content:encoded> <wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/11/23/why-is-my-scheduled-job-not-executed-in-altiris/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Altiris Job Builder</title><link>http://www.remkoweijnen.nl/blog/2010/11/23/altiris-job-builder/</link> <comments>http://www.remkoweijnen.nl/blog/2010/11/23/altiris-job-builder/#comments</comments> <pubDate>Tue, 23 Nov 2010 09:26:34 +0000</pubDate> <dc:creator>Remko</dc:creator> <category><![CDATA[Altiris]]></category> <category><![CDATA[Delphi]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[SQL Server]]></category><guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=784</guid> <description><![CDATA[I have created a little tool for myself that I have call Altiris Job Builder, it retreives the Jobs from the Altiris database and shows them in a Treeview. Then I can assemble a Master Build Job by dragging the needed Jobs to another Treeview on the right. Since it&#8217;s just for me it doesn&#8217;t [...]]]></description> <content:encoded><![CDATA[<p>I have created a little tool for myself that I have call Altiris Job Builder, it retreives the Jobs from the Altiris database and shows them in a Treeview.</p><p>Then I can assemble a Master Build Job by dragging the needed Jobs to another Treeview on the right. Since it&#8217;s just for me it doesn&#8217;t have a fancy gui:</p><p><a  href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/jobbuilder2.png" class="thickbox no_icon" rel="gallery-784" title="JobBuilder2"><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/jobbuilder2-small.png" alt="JobBuilder2" width="430" height="406" /></a></p><p>So why did I write it? Well I have divided my Jobs into Prerequisites and Packages, for instance IIS and Terminal Server and Java are prereqisuites for Citrix. But many prereqisuites are required for one or more other packages, eg Java is also used for certain applications.<span id="more-784"></span>I don&#8217;t want to make copies of Jobs since that means I have to change it in multiple places. For instance say we upgrade to a new Java version we would need to update multiple jobs instead of one (which is very likely to wrong ).</p><p>So the idea behind this master build is to create a Master Build Job that fires off all the needed jobs for a certain package. I use AxSched in an integrated script job for that. So my tool generates something like this:</p><div class="dean_ch" style="white-space: wrap;"> rem My Jobs\PKG\p003.Citrix_Prereqisuites\02.Java<br /> AxSched %COMPNAME% -jid 2000266 /t %TIME:~0,5% /ulu</p><p>rem My Jobs\PKG\p003.Citrix_Prereqisuites\03.Web-Server<br /> AxSched %COMPNAME% -jid 2000267 /t %TIME:~0,5% /ulu</p><p>rem My Jobs\PKG\p003.Citrix_Prereqisuites\05.TS_TerminalServer!<br /> AxSched %COMPNAME% -jid 2000269 /t %TIME:~0,5% /ulu</p><p>rem My Jobs\PKG\p003.Citrix_Prereqisuites\08.VisualJ#<br /> AxSched %COMPNAME% -jid 2000272 /t %TIME:~0,5% /ulu</p><p>rem My Jobs\PKG\p003.Citrix_Prereqisuites\06.CtxClient<br /> AxSched %COMPNAME% -jid 2000270 /t %TIME:~0,5% /ulu</p><p>rem My Jobs\PKG\p015.Citrix_AddServer\02.InstallCitrix!<br /> AxSched %COMPNAME% -jid 2000295 /t %TIME:~0,5% /ulu</p><p>rem My Jobs\PKG\p013.CitrixComponents\01.DeliveryServicesConsole<br /> AxSched %COMPNAME% -jid 2000287 /t %TIME:~0,5% /ulu</p><p>rem My Jobs\PKG\p013.CitrixComponents\02.CMC<br /> AxSched %COMPNAME% -jid 2000289 /t %TIME:~0,5% /ulu</p><p>rem My Jobs\PKG\p013.CitrixComponents\04.HDX<br /> AxSched %COMPNAME% -jid 2000290 /t %TIME:~0,5% /ulu</p><p>rem My Jobs\PKG\p013.CitrixComponents\03.EnableFP2<br /> AxSched %COMPNAME% -jid 2000293 /t %TIME:~0,5% /ulu</p><p>rem My Jobs\PKG\p014.CitrixHotFixes\01.HotfixRollup6!<br /> AxSched %COMPNAME% -jid 2000292 /t %TIME:~0,5% /ulu<br /> &nbsp;</div><p>But lazy as I am I don&#8217;t want to manually copy/paste this into a job but rather insert it directly into the database. If we look at the eXpress database scheme we can see that there is an event table (a Job is really an Event in Altiris):</p><p><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/eventtable.png" alt="EventTable" width="356" height="294" /></p><p>Only the event_id field is mandatory and it&#8217;s also the Primary Key of the table. However the event_id is not auto generated so if we insert a new record how do we now the right value for event_id?</p><p>One approach could be to read the highest value and increment that by 1 but that seems dangerous for various reasons. So I figured there was probably a Stored Procedure for adding a new Job/Event.</p><p>In the SQL Server Management Studio we can find Stored Procedures under the Programmability Node of the Database:</p><p><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/storedprocedures.png" alt="StoredProcedures" width="197" height="154" /></p><p>If you look into the available Stored Procedures you will see that there are del_xxx and ins_xxx events. We need the ins_event Stored Procedure:</p><p><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/11/insevent.png" alt="InsEvent" width="351" height="176" /></p><p>In Delphi we can use the TADOCommand object to call a Stored Procedure:</p><div class="dean_ch" style="white-space: wrap;"> <span class="kw1">function</span> TForm1.<span class="me1">AddEvent</span><span class="br0">&#40;</span><span class="kw1">const</span> FolderId: <span class="kw4">Integer</span>; <span class="kw1">const</span> Name: <span class="kw4">String</span>;<br /> &nbsp; <span class="kw1">const</span> Description: <span class="kw4">String</span>=<span class="st0">&#8221;</span><span class="br0">&#41;</span>: <span class="kw4">Integer</span>;<br /> <span class="kw1">var</span><br /> &nbsp; cmd: TADOCommand;<br /> <span class="kw1">begin</span><br /> &nbsp; Result := <span class="nu0">-1</span>;<br /> &nbsp; cmd := TADOCommand.<span class="me1">Create</span><span class="br0">&#40;</span><span class="kw2">nil</span><span class="br0">&#41;</span>;<br /> &nbsp; <span class="kw1">try</span><br /> &nbsp; &nbsp; cmd.<span class="me1">Connection</span> := ADOConnection1;<br /> &nbsp; &nbsp; cmd.<span class="me1">CommandType</span> := cmdStoredProc;<br /> &nbsp; &nbsp; cmd.<span class="me1">CommandText</span> := <span class="st0">&#8216;ins_event&#8217;</span>;<br /> &nbsp; &nbsp; cmd.<span class="me1">Parameters</span>.<span class="me1">Refresh</span>;<br /> &nbsp; &nbsp; cmd.<span class="me1">Parameters</span>.<span class="me1">ParamByName</span><span class="br0">&#40;</span><span class="st0">&#8216;@name&#8217;</span><span class="br0">&#41;</span>.<span class="me1">Value</span> := Name;<br /> &nbsp; &nbsp; cmd.<span class="me1">Parameters</span>.<span class="me1">ParamByName</span><span class="br0">&#40;</span><span class="st0">&#8216;@folder_id&#8217;</span><span class="br0">&#41;</span>.<span class="me1">Value</span> := FolderId;<br /> &nbsp; &nbsp; cmd.<span class="me1">Parameters</span>.<span class="me1">ParamByName</span><span class="br0">&#40;</span><span class="st0">&#8216;@description&#8217;</span><span class="br0">&#41;</span>.<span class="me1">Value</span> := Description;<br /> &nbsp; &nbsp; cmd.<span class="me1">Execute</span>;<br /> &nbsp; &nbsp; Result := cmd.<span class="me1">Parameters</span>.<span class="me1">ParamValues</span><span class="br0">&#91;</span><span class="st0">&#8216;@RETURN_VALUE&#8217;</span><span class="br0">&#93;</span>;<br /> &nbsp; <span class="kw1">finally</span><br /> &nbsp; &nbsp; cmd.<span class="me1">Free</span>;<br /> &nbsp; <span class="kw1">end</span>;<br /> <span class="kw1">end</span>;<br /> &nbsp;</div><p>The ins_event Stored Procedure returns the new JobId in the @RETURN_VALUE parameter. This is very convenient because we need the JobId to add tasks to the new Job, in this case a script task.</p><p>But enough talk for today, I hope you find the subject interesting and I would be very interested to hear about other solutions or concepts for a Master Build Job.</p> ]]></content:encoded> <wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/11/23/altiris-job-builder/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>The case of the failing Deployment Server Install</title><link>http://www.remkoweijnen.nl/blog/2010/10/26/694/</link> <comments>http://www.remkoweijnen.nl/blog/2010/10/26/694/#comments</comments> <pubDate>Tue, 26 Oct 2010 14:47:15 +0000</pubDate> <dc:creator>Remko</dc:creator> <category><![CDATA[Active Directory]]></category> <category><![CDATA[Altiris]]></category> <category><![CDATA[SQL Server]]></category> <category><![CDATA[Windows 2008]]></category><guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=694</guid> <description><![CDATA[I was trying to install HP Insight Control server deployment (previously called HP Rapid Deployment Pack) on Sql Server 2008 Express. I will just call it Deployment Server or DS from here. I first installed SQL 2008 Express with Advanced Services and configured it to listen op Port 1433 as required by DS. The installation [...]]]></description> <content:encoded><![CDATA[<p>I was trying to install HP Insight Control server deployment (<a  href="http://www.remkoweijnen.nl/blog/2010/10/14/where-to-download-hp-rapid-deployment-pack/" target="_blank">previously called HP Rapid Deployment Pack</a>) on Sql Server 2008 Express. I will just call it Deployment Server or DS from here.</p><p>I first installed SQL 2008 Express with Advanced Services and configured it to listen op Port 1433 as required by DS.</p><p>The installation of the first part (Deployment Server version 6.9.4) indicated a successfull install but the prereqisuites check of the Hotfix version 2.0 installer failed on the last step:</p><p><a  href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/10/NoAttachedConsoles.png" class="thickbox no_icon" rel="gallery-694" title="No Attached Consoles HP Deployment Server"><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/10/NoAttachedConsoles-small.png" alt="No Attached Consoles HP Deployment Server" width="430" height="300" /></a></p><p>This was strange because I didn&#8217;t yet startup the console, so I decided to start it and close it as this would perhaps allow me to continue.</p><p>The next screen was a clear indication something went wrong:</p><p><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/10/ConsoleUnableToConnect.png" alt="Altiris Deploymeny Server Unable to Connect" width="405" height="238" /></p><p>I presumed that the ODBC connection was missing so I went to Adminstrative Tools | Data Sources (ODBC). But the ODBC connection was present. I then fired up SQL Server Management Studio which showed me the eXpress database was missing.<br /> <span id="more-694"></span>Note that on x64 versions of Windows there are two versions of the ODBC connections (tool): an x86 (32 bit) and an x64 (64 bit) version.</p><p>And even worse: the HP Installer does a silent install of Altiris DS but hides this error for us and just reports success!</p><p>My next step was to do a manual database install, this can be done by starting hpfeatures\ds\Server.exe.</p><p>Server.exe fortunately allows us to install only the database:</p><p><a  href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/10/DBInstaller.png" class="thickbox no_icon" rel="gallery-694" title="DBInstaller"><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/10/DBInstaller-small.png" alt="DBInstaller" width="430" height="323" /></a></p><blockquote><p>Database installer is unpacked to a subfolder in %temp% (in my case %temp%\apt1) it may be convenient to save this folder.</p></blockquote><p>After a while the Database Installer presented and error message:</p><p><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/10/DBInstaller2.png" alt="Setup was unable to run DBInstaller.exeto create the eXpressSQL database." width="416" height="152" /></p><p>I looked into the install folder and noticed there were several .sql files (sql server scripts) and osql.exe. osql is a commandline tool that can execute sql statements and it can import .sql files.</p><p>Launching the supplied version of osql indicated that it was unable to connect to SQL at all. I did a guess that the problem was the instancename: even though you select Default Instance when installing the instance name is SQLEXPRESS instead of MSSQLSERVER (which is used in the full product).</p><p>I did a reinstall of SQL Express using a custom instance name of MSSQLSERVER and now osql could connect (it asked for credentials).</p><p>I reran the Database Install and now it worked.</p><p>In the end I am not sure if this error only happens when using the HP Branded version of Altiris or only when using SQL Express WITH advanced services but I hope this article will help you troubleshoot similar issues.</p> ]]></content:encoded> <wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/10/26/694/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Script to clear SQL Transactions logs</title><link>http://www.remkoweijnen.nl/blog/2007/10/28/script-to-clear-sql-transactions-logs/</link> <comments>http://www.remkoweijnen.nl/blog/2007/10/28/script-to-clear-sql-transactions-logs/#comments</comments> <pubDate>Sun, 28 Oct 2007 11:11:15 +0000</pubDate> <dc:creator>Remko</dc:creator> <category><![CDATA[script]]></category> <category><![CDATA[SQL Server]]></category><guid isPermaLink="false">http://remkoweijnen.nl/blog/2007/10/28/script-to-clear-sql-transactions-logs/</guid> <description><![CDATA[Script to clear SQL Transactions Logs Did you know that when you backup a SQL database with Backup Exec (with the SQL Agent) the transaction log is not cleared? This means that if you use the full recovery model your transaction log keeps growing and growing. I tested this with Backup Exec v11D and you [...]]]></description> <content:encoded><![CDATA[<p>Script to clear SQL Transactions Logs</p><p>Did you know that when you backup a SQL database with Backup Exec (with the SQL Agent) the transaction log is not cleared? This means that if you use the full recovery model your transaction log keeps growing and growing. I tested this with Backup Exec v11D and you can only create a seperate scheduled job to backup the transactions logs but not one to just clear it or truncate it after successfull backup.</p><p>Therefore I made a VBS script that clears SQL transactions logs, an option would be to schedule this as a post backup job.</p><p>This is the script:</p><p><span id="more-39"></span></p><div class="dean_ch" style="white-space: wrap;"><span class="co1">&#8216; ClrSqlLogs.vbs version 1.0</span><br /> <span class="co1">&#8216; Author: Remko Weijnen (r dot weijnen at gmail.com)</span></p><p><span class="co1">&#8216; Script to clear SQL Transaction logs</span><br /> <span class="co1">&#8216; Parameters:</span><br /> <span class="co1">&#8216; strServer = SQL Server name</span><br /> <span class="co1">&#8216; strDatabase = Database name</span><br /> <span class="co1">&#8216; strLogName = The name of the log file</span><br /> <span class="co1">&#8216;</span><br /> <span class="co1">&#8216; Script starts here:</span></p><p><span class="co1">&#8216; Force explicit declaration </span><br /> <span class="kw1">Option</span> <span class="kw1">Explicit</span></p><p><span class="co1">&#8216; Make variables public so they can be accessed from the sub</span><br /> <span class="kw1">Public</span> objCon, objCom</p><p><span class="co1">&#8216; Create database connection object</span><br /> <span class="kw1">Set</span> objCon = <span class="kw1">CreateObject</span><span class="br0">&#40;</span><span class="st0">&quot;ADODB.Connection&quot;</span><span class="br0">&#41;</span></p><p><span class="co1">&#8216; Create database command object</span><br /> <span class="kw1">Set</span> objCom = <span class="kw1">CreateObject</span><span class="br0">&#40;</span><span class="st0">&quot;ADODB.Command&quot;</span><span class="br0">&#41;</span></p><p><span class="co1">&#8216; Clear logs</span><br /> <span class="kw1">Call</span> ClearLogs<span class="br0">&#40;</span><span class="st0">&quot;MyServer&quot;</span>, <span class="st0">&quot;MyDatabase&quot;</span>, <span class="st0">&quot;MyDatabase_log&quot;</span><span class="br0">&#41;</span><br /> <span class="kw1">Call</span> ClearLogs<span class="br0">&#40;</span><span class="st0">&quot;MyOtherServer&quot;</span>, <span class="st0">&quot;MyOtherDatabase&quot;</span>, <span class="st0">&quot;MyOtherDatabase_log&quot;</span><span class="br0">&#41;</span></p><p><span class="co1">&#8216; Cleanup</span><br /> <span class="kw1">Set</span> objCom = <span class="kw1">Nothing</span><br /> <span class="kw1">Set</span> objCon = <span class="kw1">Nothing</span></p><p><span class="co1">&#8216; Exit the script (just to be sure that code below is never Executed</span><br /> WScript.<span class="me1">Quit</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></p><p><span class="co1">&#8216; The procedure that clears the log</span><br /> <span class="kw1">Sub</span> ClearLogs<span class="br0">&#40;</span>strServer, strDatabase, strLogName<span class="br0">&#41;</span><br /> &nbsp; &nbsp;<span class="kw1">Dim</span> strConnection<br /> &nbsp; &nbsp;<span class="co1">&#8216; Build connection string</span><br /> &nbsp; &nbsp;strConnection = <span class="st0">&quot;Driver={SQL Native Client};Server=&quot;</span> &amp; strServer &amp; <span class="st0">&quot;;Database=&quot;</span> &amp; strDatabase &amp; <span class="st0">&quot;;Trusted_Connection=yes;&quot;</span></p><p>&nbsp; &nbsp;WScript.<span class="me1">Echo</span><span class="br0">&#40;</span><span class="st0">&quot;Connection String: &quot;</span> &amp; strConnection<span class="br0">&#41;</span><br /> &nbsp; &nbsp;<span class="co1">&#8216; Open Connection to SQL Server and Database</span><br /> &nbsp; &nbsp;<span class="co1">&#8216; Trusted connection so the currently logged-on account needs permissions</span><br /> &nbsp; &nbsp;WScript.<span class="me1">Echo</span><span class="br0">&#40;</span><span class="st0">&quot;Open connection&quot;</span><span class="br0">&#41;</span><br /> &nbsp; &nbsp;objCon.<span class="kw1">Open</span><span class="br0">&#40;</span>strConnection<span class="br0">&#41;</span></p><p>&nbsp; &nbsp;<span class="co1">&#8216; Connect AdoCommand to the Active connection</span><br /> &nbsp; &nbsp;objCom.<span class="me1">ActiveConnection</span> = objCon<br /> &nbsp; &nbsp;<br /> &nbsp; &nbsp;<span class="co1">&#8216; Execute DBCC SHRINKFILE</span><br /> &nbsp; &nbsp;objCom.<span class="me1">CommandText</span> = <span class="st0">&quot;DBCC SHRINKFILE(&quot;</span> &amp; strLogName &amp; <span class="st0">&quot;, 1)&quot;</span><br /> &nbsp; &nbsp;WScript.<span class="me1">Echo</span><span class="br0">&#40;</span><span class="kw1">vbTab</span> &amp; objCom.<span class="me1">CommandText</span><span class="br0">&#41;</span><br /> &nbsp; &nbsp;objCom.<span class="me1">Execute</span><br /> &nbsp; &nbsp;<br /> &nbsp; &nbsp;<span class="co1">&#8216; Truncate Log</span><br /> <span class="co1">&#8216; &nbsp; WScript.Echo(vbTab &amp; &quot;BACKUP LOG WITH TRUNCAT&quot;)</span><br /> &nbsp; &nbsp;objCom.<span class="me1">CommandText</span> = <span class="st0">&quot;BACKUP LOG &quot;</span> &amp; strDatabase &amp; <span class="st0">&quot; WITH TRUNCATE_ONLY&quot;</span><br /> &nbsp; &nbsp;WScript.<span class="me1">Echo</span><span class="br0">&#40;</span><span class="kw1">vbTab</span> &amp; objCom.<span class="me1">CommandText</span><span class="br0">&#41;</span><br /> &nbsp; &nbsp;objCom.<span class="me1">Execute</span></p><p>&nbsp; &nbsp;<span class="co1">&#8216; Execute DBCC SHRINKFILE again &nbsp;</span><br /> &nbsp; &nbsp;objCom.<span class="me1">CommandText</span> = <span class="st0">&quot;DBCC SHRINKFILE(&quot;</span> &amp; strLogName &amp; <span class="st0">&quot;, 1)&quot;</span><br /> &nbsp; &nbsp;objCom.<span class="me1">Execute</span><br /> &nbsp; &nbsp;WScript.<span class="me1">Echo</span><span class="br0">&#40;</span><span class="st0">&quot;Close connection&quot;</span><span class="br0">&#41;</span><br /> &nbsp; &nbsp;objCon.<span class="kw1">Close</span><br /> <span class="kw1">End</span> <span class="kw1">Sub</span><br /> &nbsp;</div> <a  class="downloadlink" href="http://www.remkoweijnen.nl/blog/download/ClrSQLLogs.zip" title="Version1.0 downloaded 163 times">ClrSQLLogs.zip (163)</a> ]]></content:encoded> <wfw:commentRss>http://www.remkoweijnen.nl/blog/2007/10/28/script-to-clear-sql-transactions-logs/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> </channel> </rss>
