<?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>Dwarfsoft [GPA] &#187; Script</title>
	<atom:link href="http://www.dwarfsoft.com/blog/tag/script/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dwarfsoft.com/blog</link>
	<description>Great Programming Artistry</description>
	<lastBuildDate>Tue, 22 Jun 2010 21:01:59 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Group Policy Editing &#8211; Findings</title>
		<link>http://www.dwarfsoft.com/blog/2010/06/15/group-policy-editing-findings/</link>
		<comments>http://www.dwarfsoft.com/blog/2010/06/15/group-policy-editing-findings/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 03:16:01 +0000</pubDate>
		<dc:creator>dwarfsoft</dc:creator>
				<category><![CDATA[Novell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[Domain]]></category>
		<category><![CDATA[eDirectory]]></category>
		<category><![CDATA[Group Policy]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Profile]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[VBScript]]></category>

		<guid isPermaLink="false">http://www.dwarfsoft.com/blog/?p=309</guid>
		<description><![CDATA[I had started another post on Group Policy editing, and how the Policy files are structured, and how to use and improve on the existing Group Policy Editor tool. The post has been found to be far too epic, so I have decided to cover a smaller subset of recent finds. 
As everybody is probably [...]]]></description>
			<content:encoded><![CDATA[<p>I had started another post on Group Policy editing, and how the Policy files are structured, and how to use and improve on the existing Group Policy Editor tool. The post has been found to be far too epic, so I have decided to cover a smaller subset of recent finds. </p>
<p>As everybody is probably already aware, we use Novell ConsoleOne and Zenworks where I work. ConsoleOne has some interesting features that require that whenever a Group Policy is being edited it takes over as the policy on the machine that is editing it. Rather than have a useful tool like Microsofts Group Policy Management Console, Novell likes to replace the local Group Policy and then just run gpedit.msc. Which is where my first gripe about gpedit.msc comes in:</p>
<p>GPEdit.msc requires line by line entry of things like, for example, port exceptions and program exceptions for the Windows Firewall. This is usually not an issue except that, as I have discussed in previous posts, we have been moving towards a Windows Domain environment. Firewall Exception rules are configured within two places in Group Policy: Domain Profile and Standard Profile. I have found that there is a need to move our current Standard Profile settings across to the Domain Profile settings. After a bit of registry searching I found a neat trick for doing exactly that.</p>
<p><span id="more-309"></span></p>
<p>In Novell, when a GPO is opened in gpedit.msc the Group Policy Contents are loaded into the normal registry locations (as per a normal GPO being applied to user and machine) and the contents are also loaded under a specific pair of registry keys. The <strong>HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects</strong> Key is created on loading gpedit.msc, and underneath a pair of Keys are created like <strong>{449E44B0-A4DC-4665-AE8F-68710E1BC1EC}Machine</strong> and <strong>{449E44B0-A4DC-4665-AE8F-68710E1BC1EC}User</strong>, where the GUID is randomly generated  (or at least seems to be random) each time gpedit.msc is run. Under these keys are the branch on which the Group Policy Settings are configured.</p>
<p>So therefore in order to duplicate StandardProfile Settings I need to duplicate all keys and values underneath <strong>HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\<em>{GUID}</em>Machine\Software\Policies\Microsoft\WindowsFirewall\StandardProfile\</strong>, where {GUID} is the randomly generated GUID for editing a Group Policy Object. So far from my research I have never seen more than one GUID appear underneath the <strong>Group Policy Objects</strong> key, though your mileage may vary. So the first step is to get the User and Machine keys from under the Group Policy Objects key.</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Const</span> HKEY_CURRENT_USER = &amp;H80000001
<span style="color: #000080;">Const</span> HKEY_LOCAL_MACHINE = &amp;H80000002
&nbsp;
<span style="color: #000080;">Const</span> REG_SZ = 1
<span style="color: #000080;">Const</span> REG_EXPAND_SZ = 2
<span style="color: #000080;">Const</span> REG_BINARY = 3
<span style="color: #000080;">Const</span> REG_DWORD = 4
<span style="color: #000080;">Const</span> REG_MULTI_SZ = 7
&nbsp;
strComputer = <span style="color: #800000;">&quot;.&quot;</span>
&nbsp;
<span style="color: #000080;">Set</span> objReg=GetObject(<span style="color: #800000;">&quot;winmgmts:{impersonationLevel=impersonate}!\\&quot;</span> &amp; _
 strComputer &amp; <span style="color: #800000;">&quot;\root\default:StdRegProv&quot;</span>)
&nbsp;
strKeyPath = <span style="color: #800000;">&quot;Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\&quot;</span>
strStandardPath = <span style="color: #800000;">&quot;\Software\Policies\Microsoft\WindowsFirewall\StandardProfile\&quot;</span>
strDomainPath = <span style="color: #800000;">&quot;\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\&quot;</span>
&nbsp;
<span style="color: #000080;">If</span> keyExists(HKEY_CURRENT_USER,strKeyPath) <span style="color: #000080;">Then</span>
  subkeys = GetSubkeys(HKEY_CURRENT_USER,strKeyPath)
  <span style="color: #000080;">If</span> <span style="color: #000080;">Not</span> IsEmpty(subkeys) <span style="color: #000080;">Then</span>
    GPOMachine = subkeys(<span style="color: #000080;">LBound</span>(subkeys)) 
    GPOUser    = subkeys(<span style="color: #000080;">UBound</span>(subkeys))
&nbsp;
    RegCopyTree HKEY_CURRENT_USER, strKeyPath &amp; GPOMachine &amp; strStandardPath, strKeyPath &amp; GPOMachine &amp; strDomainPath, <span style="color: #000080;">False</span>
  <span style="color: #000080;">Else</span>
    WScript.Echo <span style="color: #800000;">&quot;Policy not found, please try editing the policy manually&quot;</span>
  <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
<span style="color: #000080;">Else</span>
  WScript.Echo <span style="color: #800000;">&quot;Please start editing the Group Policy before running this script&quot;</span>
<span style="color: #000080;">End</span> <span style="color: #000080;">If</span></pre></div></div>

<p>The code here is the shell of the script. We need to flesh out the functions keyExists, GetSubkeys, RegCopyTree, and valueExists (which we can&#8217;t see just yet). So first we will have a look at keyExists:</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> keyExists(Hive, Key)
  <span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Resume</span> <span style="color: #000080;">Next</span>
  Err.Clear
&nbsp;
  ret = objReg.EnumValues(Hive,Key,arrValues,arrValueTypes)
&nbsp;
  <span style="color: #000080;">If</span> ret &lt;&gt; 0 <span style="color: #000080;">Then</span>
    keyExists = <span style="color: #000080;">False</span>
  <span style="color: #000080;">Else</span>
    keyExists = <span style="color: #000080;">True</span>
  <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
  Err.Clear
  <span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Goto</span> 0
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>Fairly straightforward, we try and enumerate the values of a key. If we succeed then the key does exist, otherwise it doesn&#8217;t. We will use the same principle for checking if a Value Exists.</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> valueExists(Hive, Key, ValueName)
  <span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Resume</span> <span style="color: #000080;">Next</span>
  Err.Clear
&nbsp;
  valueExists = <span style="color: #000080;">False</span>
  <span style="color: #000080;">If</span> <span style="color: #000080;">Not</span> keyExists(Hive, Key) <span style="color: #000080;">Then</span>
    <span style="color: #000080;">Exit</span> <span style="color: #000080;">Function</span>
  <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
&nbsp;
  ret = objReg.EnumValues(Hive,Key,arrValues,arrValueTypes)
&nbsp;
  <span style="color: #000080;">If</span> IsNull(arrValues) <span style="color: #000080;">Then</span>
    <span style="color: #000080;">Exit</span> <span style="color: #000080;">Function</span>
  <span style="color: #000080;">End</span> <span style="color: #000080;">IF</span>
&nbsp;
  <span style="color: #000080;">For</span> i = <span style="color: #000080;">LBound</span>(arrValues) <span style="color: #000080;">to</span> <span style="color: #000080;">UBound</span>(arrValues)
    <span style="color: #000080;">If</span> LCase(<span style="color: #000080;">CStr</span>(arrValues(i))) = LCase(<span style="color: #000080;">CStr</span>(ValueName)) <span style="color: #000080;">Then</span>
	  valueExists = <span style="color: #000080;">True</span>
	  <span style="color: #000080;">Exit</span> <span style="color: #000080;">Function</span>
	<span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
  <span style="color: #000080;">Next</span>
&nbsp;
  valueExists = <span style="color: #000080;">False</span>
&nbsp;
  Err.Clear
  <span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Goto</span> 0
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>Here, we take the Enumeration of the Keys Values a step further and actually step through them looking for a match with ValueName. I have opted for a Case Insensitive search due to registry being case insensitive with value names.</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> GetSubkeys(Hive, Key)
  <span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Resume</span> <span style="color: #000080;">Next</span>
  Err.Clear
&nbsp;
  ret = objReg.EnumKey(Hive,Key,arrSubkeys)
&nbsp;
  GetSubkeys = arrSubkeys
&nbsp;
  Err.Clear
  <span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Goto</span> 0
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>Possibly the simplest of the functions, GetSubkeys just returns an array of Keys underneath the current Key. The most indepth function we require is the RegCopyTree:</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> RegCopyTree(Hive, SrcKey, DestKey, Force)
  <span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Resume</span> <span style="color: #000080;">Next</span>
  Err.Clear
  strComputer = <span style="color: #800000;">&quot;.&quot;</span>
  <span style="color: #000080;">Set</span> StdOut = WScript.StdOut
  strValue = <span style="color: #800000;">&quot;&quot;</span>
  <span style="color: #000080;">If</span> Force &lt;&gt; <span style="color: #000080;">True</span> <span style="color: #000080;">Then</span>
    Force = <span style="color: #000080;">False</span>
  <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
&nbsp;
  <span style="color: #000080;">if</span> Right(SrcKey,1) &lt;&gt; <span style="color: #800000;">&quot;\&quot;</span> <span style="color: #000080;">Then</span> SrcKey = SrcKey &amp; <span style="color: #800000;">&quot;\&quot;</span>
  <span style="color: #000080;">if</span> Right(DestKey,1) &lt;&gt; <span style="color: #800000;">&quot;\&quot;</span> <span style="color: #000080;">Then</span> DestKey = DestKey &amp; <span style="color: #800000;">&quot;\&quot;</span>
&nbsp;
  ret = objReg.EnumValues(Hive,SrcKey,arrValueNames,arrValueTypes)
&nbsp;
  <span style="color: #000080;">For</span> i= <span style="color: #000080;">LBound</span>(arrValueNames) <span style="color: #000080;">To</span> <span style="color: #000080;">UBound</span>(arrValueNames)
    <span style="color: #008000;">'StdOut.WriteLine &quot;Value Name: &quot; &amp; arrValueNames(i) 
</span>	StdOut.WriteLine <span style="color: #800000;">&quot;Copying from: &quot;</span> &amp; SrcKey &amp; arrValueNames(i)
	StdOut.WriteLine <span style="color: #800000;">&quot;To          : &quot;</span> &amp; DestKey &amp; arrValueNames(i)
    StdOut.Write     <span style="color: #800000;">&quot;       Value: &quot;</span>
&nbsp;
	<span style="color: #000080;">If</span> (<span style="color: #000080;">Not</span> valueExists(Hive, DestKey, arrValueNames(i))) <span style="color: #000080;">Or</span> Force <span style="color: #000080;">Then</span>
	  <span style="color: #000080;">Select</span> <span style="color: #000080;">Case</span> arrValueTypes(i)
			<span style="color: #000080;">Case</span> REG_SZ
				<span style="color: #008000;">'StdOut.WriteLine &quot;Data Type: String&quot;
</span>				<span style="color: #008000;">'StdOut.WriteBlankLines(1)
</span>				
				objReg.GetStringValue Hive, SrcKey, arrValueNames(i), strValue
				objReg.SetStringValue Hive, DestKey, arrValueNames(i), strValue
				StdOut.Write strValue
			<span style="color: #000080;">Case</span> REG_EXPAND_SZ
				<span style="color: #008000;">'StdOut.WriteLine &quot;Data Type: Expanded String&quot;
</span>				<span style="color: #008000;">'StdOut.WriteBlankLines(1)
</span>				
				objReg.GetExpandedStringValue Hive, SrcKey, arrValueNames(i), strValue
				objReg.SetExpandedStringValue Hive, DestKey, arrValueNames(i), strValue
				StdOut.Write strValue
&nbsp;
			<span style="color: #000080;">Case</span> REG_BINARY
				<span style="color: #008000;">'StdOut.WriteLine &quot;Data Type: Binary&quot;
</span>				<span style="color: #008000;">'StdOut.WriteBlankLines(1)
</span>				
				objReg.GetBinaryValue Hive, SrcKey, arrValueNames(i), strValue
				objReg.SetBinaryValue Hive, DestKey, arrValueNames(i), strValue
				<span style="color: #000080;">For</span> <span style="color: #000080;">Each</span> x <span style="color: #000080;">in</span> strValue
		          StdOut.Write Hex(x) &amp; <span style="color: #800000;">&quot; &quot;</span>
		        <span style="color: #000080;">Next</span>
&nbsp;
			<span style="color: #000080;">Case</span> REG_DWORD
				<span style="color: #008000;">'StdOut.WriteLine &quot;Data Type: DWORD&quot;
</span>				<span style="color: #008000;">'StdOut.WriteBlankLines(1)
</span>				
				objReg.GetDWORDValue Hive, SrcKey, arrValueNames(i), strValue
				objReg.SetDWordValue Hive, DestKey, arrValueNames(i), strValue
&nbsp;
				StdOut.Write Hex(strValue)
			<span style="color: #000080;">Case</span> REG_MULTI_SZ
				<span style="color: #008000;">'StdOut.WriteLine &quot;Data Type: Multi String&quot;
</span>				<span style="color: #008000;">'StdOut.WriteBlankLines(1)
</span>				
				objReg.GetMultiStringValue Hive, SrcKey, arrValueNames(i), strValue
				objReg.SetMultiStringValue Hive, DestKey, arrValueNames(i), strValue
				<span style="color: #000080;">For</span> <span style="color: #000080;">Each</span> x <span style="color: #000080;">in</span> strValue
		          StdOut.Write x
		        <span style="color: #000080;">Next</span>
		<span style="color: #000080;">End</span> <span style="color: #000080;">Select</span> 
&nbsp;
		StdOut.WriteLine <span style="color: #800000;">&quot;&quot;</span>
    <span style="color: #000080;">End</span> <span style="color: #000080;">If</span> <span style="color: #008000;">'' Force
</span>  <span style="color: #000080;">Next</span>
&nbsp;
  ret = objReg.EnumKey(Hive,SrcKey,arrSubkeys)
&nbsp;
  <span style="color: #000080;">For</span> i = <span style="color: #000080;">LBound</span>(arrSubkeys) <span style="color: #000080;">to</span> <span style="color: #000080;">UBound</span>(arrSubkeys)
    <span style="color: #000080;">If</span> <span style="color: #000080;">Not</span> keyExists(Hive,DestKey &amp; arrSubkeys(i)) <span style="color: #000080;">Then</span>
	  objReg.CreateKey Hive,DestKey &amp; arrSubkeys(i)
	<span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
	RegCopyTree Hive, SrcKey &amp; arrSubkeys(i), DestKey &amp; arrSubkeys(i), Force
  <span style="color: #000080;">Next</span>
&nbsp;
  <span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Goto</span> 0
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>This function takes the Hive, Source Key, Destination Key, and a Boolean Value to determine whether to Force overwriting existing values. It first creates the Destination key if it doesn&#8217;t already exist, then enumerates all values in the Source path, and writes them to the Destination path, creating new values or overwriting only if Force is set. This function has a lot of StdOut.Write calls to show the progress of the duplication. Running the script via CScript gives the following results:</p>
<pre>Copying from: Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\{678C8897-54AA-4FB9-AA72-6C227C287D12}Machine\Software\Policies\Microsoft\WindowsFirewall\StandardProfile\EnableFirewall
To          : Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\{678C8897-54AA-4FB9-AA72-6C227C287D12}Machine\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\EnableFirewall
       Value: 1
Copying from: Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\{678C8897-54AA-4FB9-AA72-6C227C287D12}Machine\Software\Policies\Microsoft\WindowsFirewall\StandardProfile\AuthorizedApplications\Enabled
To          : Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\{678C8897-54AA-4FB9-AA72-6C227C287D12}Machine\Software\Policies\Microsoft\WindowsFirewall\DomainProfile\AuthorizedApplications\Enabled
       Value: 1
...</pre>
<p>This should simplify the time taken for duplicating from Standard to Domain profile. For future reference this has also made it far easier to import/export port/program exceptions from policies I am editing. In future I may incorporate this into my Group Policy Firewall Exceptions Excel Spreadsheet in VBA to allow writing updated policies to the Policy.</p>
<p>After running this the settings will be seen to have changed in the Group Policy Editor Window immediately. I have tested this and checked that the Logging file is not replaced by &#8220;&#8230;\standard.log&#8221; where it should be &#8220;&#8230;\domain.log&#8221;.</p>
<p>Cheers, Chris.</p>
<p>Attached: <a href='http://www.dwarfsoft.com/blog/wp-content/uploads/2010/06/RegFirewallProfileDuplication.vbs_.txt'>RegFirewallProfileDuplication.vbs</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dwarfsoft.com/blog/2010/06/15/group-policy-editing-findings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Last Login Time</title>
		<link>http://www.dwarfsoft.com/blog/2010/04/22/last-login-time/</link>
		<comments>http://www.dwarfsoft.com/blog/2010/04/22/last-login-time/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 01:54:33 +0000</pubDate>
		<dc:creator>dwarfsoft</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[bginfo]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[VBScript]]></category>

		<guid isPermaLink="false">http://www.dwarfsoft.com/blog/?p=300</guid>
		<description><![CDATA[I have recently been having a look into determining the Last Login Time of a user for a BGInfo implementation. Firstly I had a look at the getCurrentUserLastLoginTime script suggested for use with BGInfo. The limitation of this script, however, is that it will reset the login time to the last time the Windows login [...]]]></description>
			<content:encoded><![CDATA[<p>I have recently been having a look into determining the Last Login Time of a user for a BGInfo implementation. Firstly I had a look at the <a href="http://slingfive.com/pages/code/bgInfo_scripts/scripts/getCurrentUserLastLoginTime.vbs">getCurrentUserLastLoginTime script</a> suggested for use with BGInfo. The limitation of this script, however, is that it will reset the login time to the last time the Windows login box was Authenticated against, which also includes the time that the workstation was unlocked.</p>
<p>In order to maintain current BGInfo information the implementation is running periodically, so this is unnacceptable. Therefore I had to work to resolve the issue manually. As I have had a fair bit of experience with Windows Profiles recently (see the <a href="http://www.dwarfsoft.com/blog/2010/03/15/shared-user-profiles-staging-scripts/">last blog post</a>) I was familiar with the ProfileLoadTimeHigh and ProfileLoadTimeLow registry keys in the ProfileList. So I set out to determine how to actually use these to determine the login time. I first wrote some code to get the User SID based on the users &#8220;%userdomain%&#8221; and &#8220;%username%&#8221;:</p>
<p><span id="more-300"></span></p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">DIM</span> oNet, strComputerName, strUserName, strUserDomain
<span style="color: #000080;">SET</span> oNet = CreateObject(<span style="color: #800000;">&quot;WScript.Network&quot;</span>)
strComputerName = oNet.Computername
strUserName = oNet.UserName
strUserDomain = oNet.UserDomain
<span style="color: #000080;">SET</span> oNet = <span style="color: #000080;">nothing</span>
&nbsp;
<span style="color: #000080;">Set</span> WMI = GetObject(<span style="color: #800000;">&quot;winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2&quot;</span>)
&nbsp;
SubKey = <span style="color: #800000;">&quot;&quot;</span>
&nbsp;
<span style="color: #000080;">Set</span> wmiCol = WMI.ExecQuery (<span style="color: #800000;">&quot;SELECT Domain, Name, SID FROM Win32_Account where Name=&quot;</span><span style="color: #800000;">&quot;&quot;</span>&amp;strUserName&amp;<span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot; And Domain=&quot;</span><span style="color: #800000;">&quot;&quot;</span>&amp;strUserDomain&amp;<span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;&quot;</span>)
<span style="color: #000080;">For</span> <span style="color: #000080;">each</span> wmiItem <span style="color: #000080;">in</span> wmiCol
  SubKey = wmiItem.SID
  <span style="color: #000080;">Exit</span> <span style="color: #000080;">For</span>
<span style="color: #000080;">Next</span></pre></div></div>

<p>So I set Subkey to be the String SID of the user, which I could then use to read the ProfileLoadTimeHigh and ProfileLoadTimeLow keys for the correct profile. I used the basic script from <a href="http://www.myitforum.com/forums/tm.aspx?high=&#038;m=163289&#038;mpage=1#163289">MyITForum</a>, however this failed to take into account the timezone on the local machine. Therefore the first thing I needed to do was get the users timezone.</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;">tz = 0
<span style="color: #000080;">For</span> <span style="color: #000080;">Each</span> os <span style="color: #000080;">In</span> GetObject(<span style="color: #800000;">&quot;winmgmts:&quot;</span>).InstancesOf (<span style="color: #800000;">&quot;Win32_OperatingSystem&quot;</span>)
  tz = os.CurrentTimeZone
  <span style="color: #000080;">Exit</span> <span style="color: #000080;">For</span>  
<span style="color: #000080;">Next</span></pre></div></div>

<p>Then I integrated the Timezone offset (in minutes) into the <a href="http://www.myitforum.com/forums/tm.aspx?high=&#038;m=163289&#038;mpage=1#163289">original ProfileLoadTime script</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Const</span> HKEY_LOCAL_MACHINE = &amp;H80000002
&nbsp;
strReturn = <span style="color: #800000;">&quot;&quot;</span>
&nbsp;
<span style="color: #000080;">Set</span> objReg = GetObject(<span style="color: #800000;">&quot;winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv&quot;</span>  )
strKeyPath = <span style="color: #800000;">&quot;SOFTWARE\MICROSOFT\Windows NT\CurrentVersion\ProfileList\&quot;</span> &amp; SubKey 
&nbsp;
strValueName = <span style="color: #800000;">&quot;ProfileLoadTimeHigh&quot;</span>
Return = objReg.GetDWORDValue(HKEY_LOCAL_MACHINE,strKeyPath,strValueName,lngHighValue)
strValueName = <span style="color: #800000;">&quot;ProfileLoadTimeLow&quot;</span>
Return = objReg.GetDWORDValue(HKEY_LOCAL_MACHINE,strKeyPath,strValueName,lngLowValue)
<span style="color: #000080;">If</span> typename(lngHighValue) &lt;&gt; <span style="color: #800000;">&quot;Null&quot;</span> <span style="color: #000080;">then</span>
  NanoSecs = (lngHighValue * 2 ^ 32 + lngLowValue)
  <span style="color: #008000;">'' /* Returns time in Workstation Timezone */
</span>  DT = #1/1/1601# + (NanoSecs / 600000000 / 1440) + (tz / 1440)
  strReturn = <span style="color: #000080;">CDate</span>(DT)
<span style="color: #000080;">End</span> <span style="color: #000080;">if</span></pre></div></div>

<p>Finally the output is printed as per a standard BGInfo script</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Resume</span> <span style="color: #000080;">Next</span>
	<span style="color: #000080;">call</span> WScript.Echo(strReturn)	<span style="color: #008000;">'for cmd line
</span>	<span style="color: #000080;">call</span> Echo(strReturn)	<span style="color: #008000;">'for BGInfo
</span><span style="color: #000080;">on</span> <span style="color: #000080;">error</span> <span style="color: #000080;">goto</span> 0</pre></div></div>

<p>This works for Power Users as well, which the original script did not (due to permissions issues). Hope this helped you in some way <img src='http://www.dwarfsoft.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Cheers, Chris.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dwarfsoft.com/blog/2010/04/22/last-login-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shared User Profiles &#8211; Staging Scripts</title>
		<link>http://www.dwarfsoft.com/blog/2010/03/15/shared-user-profiles-staging-scripts/</link>
		<comments>http://www.dwarfsoft.com/blog/2010/03/15/shared-user-profiles-staging-scripts/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 05:19:40 +0000</pubDate>
		<dc:creator>dwarfsoft</dc:creator>
				<category><![CDATA[Novell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[Domain]]></category>
		<category><![CDATA[eDirectory]]></category>
		<category><![CDATA[Hack]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Profile]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[User Accounts]]></category>
		<category><![CDATA[VBScript]]></category>

		<guid isPermaLink="false">http://www.dwarfsoft.com/blog/?p=291</guid>
		<description><![CDATA[As promised, here are the scripts required for the Pre-staging of Domain User Profiles on the local machine. The first thing we need to do is Enumerate all the Local User Accounts.

Function StageAllUsers(DomainFQDN, strDomain)
   ' Enumerate all users that are Local and not built in accounts.
   strComputer = &#34;.&#34;
   [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.dwarfsoft.com/blog/2010/03/12/shared-user-profiles-alternative-to-migration/">As promised</a>, here are the scripts required for the Pre-staging of Domain User Profiles on the local machine. The first thing we need to do is Enumerate all the Local User Accounts.</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> StageAllUsers(DomainFQDN, strDomain)
   <span style="color: #008000;">' Enumerate all users that are Local and not built in accounts.
</span>   strComputer = <span style="color: #800000;">&quot;.&quot;</span>
   <span style="color: #000080;">Set</span> objWMIService = GetObject(<span style="color: #800000;">&quot;winmgmts:\\&quot;</span> &amp; strComputer &amp; <span style="color: #800000;">&quot;\root\cimv2&quot;</span>)
   <span style="color: #008000;">'Enumerate users where the User Domain is the Local Machine
</span>   <span style="color: #000080;">Set</span> colItems = objWMIService.ExecQuery _
                  (<span style="color: #800000;">&quot;Select * from Win32_UserAccount &quot;</span> &amp; _
                   <span style="color: #800000;">&quot;Where Domain = '&quot;</span> &amp; GetComputerName &amp; <span style="color: #800000;">&quot;' &quot;</span> &amp; _
                   <span style="color: #800000;">&quot;And Disabled = FALSE And Name &lt;&gt; 'Administrator'&quot;</span>)
   <span style="color: #008000;">' Stage each user
</span>   <span style="color: #000080;">For</span> <span style="color: #000080;">Each</span> objItem <span style="color: #000080;">In</span> colItems
      <span style="color: #008000;">' Ensure the account actually has a profile (otherwise we can ignore it)
</span>      <span style="color: #000080;">If</span> GetLocalUserProfile(objItem.Name) &lt;&gt; <span style="color: #800000;">&quot;&quot;</span> <span style="color: #000080;">Then</span>
         ret = StageUser(objItem.Name, DomainFQDN, strDomain)
      <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
   <span style="color: #000080;">Next</span>
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>The functions called here are GetComputerName, which returns the name of the local machine, and the other important ones are GetLocalUserProfile and Stage User. The first we can check is GetLocalUserProfile.<span id="more-291"></span></p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #008000;">'Gets the Profile Path for the User passed in UserName.
</span><span style="color: #008000;">' This requires the profile to exist on the local machine
</span><span style="color: #008000;">' Returns an empty string on error
</span><span style="color: #000080;">Function</span> GetLocalUserProfile(UserName)
   <span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Resume</span> <span style="color: #000080;">Next</span>
   GetLocalUserProfile = <span style="color: #800000;">&quot;&quot;</span>
   SDDL = GetLocalUserSDDL(UserName)
   <span style="color: #000080;">If</span> SDDL = <span style="color: #800000;">&quot;&quot;</span> <span style="color: #000080;">Then</span>
      <span style="color: #000080;">Exit</span> <span style="color: #000080;">Function</span>
   <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
   <span style="color: #000080;">Set</span> objShell = CreateObject(<span style="color: #800000;">&quot;WScript.Shell&quot;</span>)
   GetLocalUserProfile = objShell.ExpandEnvironmentStrings( _
                            objShell.RegRead( _
                               <span style="color: #800000;">&quot;HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList\&quot;</span> &amp; _
                               SDDL &amp; _
                               <span style="color: #800000;">&quot;\ProfileImagePath&quot;</span>))
  <span style="color: #000080;">On</span> <span style="color: #000080;">Error</span> <span style="color: #000080;">Goto</span> 0
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>The registry path (including the SDDL, covered next) returns the profile path for the user. This relies on a function called GetLocalUserSDDL which goes as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> GetLocalUserSDDL(UserName)
   strComputer = <span style="color: #800000;">&quot;.&quot;</span>
   <span style="color: #000080;">Set</span> objWMIService = GetObject(<span style="color: #800000;">&quot;winmgmts:\\&quot;</span> &amp; strComputer &amp; <span style="color: #800000;">&quot;\root\cimv2&quot;</span>)
   <span style="color: #008000;">'Enumerate users where the User Domain is the Local Machine
</span>   <span style="color: #008000;">'and the username matches the Supplied Name
</span>   <span style="color: #000080;">Set</span> colItems = objWMIService.ExecQuery _
                     (<span style="color: #800000;">&quot;Select * from Win32_UserAccount  &quot;</span> &amp; _
                      <span style="color: #800000;">&quot;Where Domain = '&quot;</span> &amp; GetComputerName &amp; <span style="color: #800000;">&quot;' &quot;</span> &amp; _
                      <span style="color: #800000;">&quot;And Name = '&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;'&quot;</span>)
   GetLocalUserSDDL = <span style="color: #800000;">&quot;&quot;</span>
   <span style="color: #000080;">For</span> <span style="color: #000080;">Each</span> objItem <span style="color: #000080;">In</span> colItems
      <span style="color: #008000;">'Get the first returned SID/SDDL then exit
</span>      GetLocalUserSDDL = objItem.SID
      <span style="color: #000080;">Exit</span> <span style="color: #000080;">Function</span>
   <span style="color: #000080;">Next</span>
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>This reads the SDDL (eg S-1-5-21-791012361-4073638415-1907800938-1006 or otherwise known as the String SID) for the User on the local machine. The next major function is Stage User:</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> StageUser(UserName, DomainFQDN, strDomain)
   <span style="color: #000080;">Set</span> objShell = CreateObject(<span style="color: #800000;">&quot;WScript.Shell&quot;</span>)
   <span style="color: #008000;">' Not Assuming &quot;C:\Documents and Settings\&quot; &amp; UserName:
</span>   <span style="color: #008000;">'   Get SDDL of user via WMI interrogation of UserAccount
</span>   <span style="color: #008000;">'   Get Profile Location of user (from HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList\&quot; &amp; SDDL &amp; &quot;ProfileImagePath&quot;
</span>   strProfile = GetLocalUserProfile(UserName)
&nbsp;
   <span style="color: #008000;">' Set ACLs on ProfileLocation
</span>   ret = objShell.Run(<span style="color: #800000;">&quot;subinacl /subdirectories &quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; strProfile &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot; /grant=&quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;@&quot;</span> &amp; DomainFQDN &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;=F&quot;</span>,0,<span style="color: #000080;">True</span>)
&nbsp;
   <span style="color: #008000;">' Set ACLs on D:\UserData\%username%
</span>   ret = objShell.Run(<span style="color: #800000;">&quot;subinacl /subdirectories &quot;</span><span style="color: #800000;">&quot;D:\UserData\&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot; /grant=&quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;@&quot;</span> &amp; DomainFQDN &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;=F&quot;</span>,0,<span style="color: #000080;">True</span>)
&nbsp;
   <span style="color: #008000;">' Reg load ProfileLocation\NTUSER.DAT into HKU\%username%
</span>   ret = objShell.Run(<span style="color: #800000;">&quot;reg load &quot;</span><span style="color: #800000;">&quot;HKU\&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot; &quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; strProfile &amp; <span style="color: #800000;">&quot;\NTUSER.DAT&quot;</span><span style="color: #800000;">&quot;&quot;</span> ,0,<span style="color: #000080;">True</span>)
   <span style="color: #008000;">' Reg load ProfileLocation\Local Settings\Application Data\Microsoft\Windows\UsrClass.DAT into HKU\%username%_Classes
</span>   ret = objShell.Run(<span style="color: #800000;">&quot;reg load &quot;</span><span style="color: #800000;">&quot;HKU\&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;_Classes&quot;</span><span style="color: #800000;">&quot; &quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; strProfile &amp; <span style="color: #800000;">&quot;\Local Settings\Application Data\Microsoft\Windows\UsrClass.DAT&quot;</span><span style="color: #800000;">&quot;&quot;</span> ,0,<span style="color: #000080;">True</span>)
&nbsp;
   <span style="color: #008000;">'Try both of the following. One should fail, the other should pass.
</span>   <span style="color: #008000;">' Set ACLs on HKU\%username%
</span>   ret = objShell.Run(<span style="color: #800000;">&quot;subinacl /subkeyreg &quot;</span><span style="color: #800000;">&quot;HKEY_USERS\&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot; /grant=&quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;@&quot;</span> &amp; DomainFQDN &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;=F&quot;</span>,0,<span style="color: #000080;">True</span>)
   <span style="color: #008000;">' If User is already logged in then the registry will be open at HKU\SDDL
</span>   ret = objShell.Run(<span style="color: #800000;">&quot;subinacl /subkeyreg &quot;</span><span style="color: #800000;">&quot;HKEY_USERS\&quot;</span> &amp; GetLocalUserSDDL(UserName) &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot; /grant=&quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;@&quot;</span> &amp; DomainFQDN &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;=F&quot;</span>,0,<span style="color: #000080;">True</span>)
&nbsp;
   <span style="color: #008000;">'Try both of the following. One should fail, the other should pass.
</span>   <span style="color: #008000;">' Set ACLs on HKU\%username%
</span>   ret = objShell.Run(<span style="color: #800000;">&quot;subinacl /subkeyreg &quot;</span><span style="color: #800000;">&quot;HKEY_USERS\&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;_Classes&quot;</span><span style="color: #800000;">&quot; /grant=&quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;@&quot;</span> &amp; DomainFQDN &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;=F&quot;</span>,0,<span style="color: #000080;">True</span>)
   <span style="color: #008000;">' If User is already logged in then the registry will be open at HKU\SDDL
</span>   ret = objShell.Run(<span style="color: #800000;">&quot;subinacl /subkeyreg &quot;</span><span style="color: #800000;">&quot;HKEY_USERS\&quot;</span> &amp; GetLocalUserSDDL(UserName) &amp; <span style="color: #800000;">&quot;_Classes&quot;</span><span style="color: #800000;">&quot; /grant=&quot;</span><span style="color: #800000;">&quot;&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;@&quot;</span> &amp; DomainFQDN &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;=F&quot;</span>,0,<span style="color: #000080;">True</span>)
&nbsp;
   <span style="color: #008000;">' Reg unload HKU\%username%
</span>   ret = objShell.Run(<span style="color: #800000;">&quot;reg unload &quot;</span><span style="color: #800000;">&quot;HKU\&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;&quot;</span>,0,<span style="color: #000080;">True</span>)
   <span style="color: #008000;">' Reg unload HKU\%username%_Classes
</span>   ret = objShell.Run(<span style="color: #800000;">&quot;reg unload &quot;</span><span style="color: #800000;">&quot;HKU\&quot;</span> &amp; UserName &amp; <span style="color: #800000;">&quot;_Classes&quot;</span><span style="color: #800000;">&quot;&quot;</span>,0,<span style="color: #000080;">True</span>)
&nbsp;
   <span style="color: #008000;">' Get Domain User SID from ProfileLocation ACL
</span>   arrSID = GetDomainUserSidFromFolderACL(strProfile, UserName, strDomain)
&nbsp;
   <span style="color: #000080;">If</span> <span style="color: #000080;">UBound</span>(arrSID) &gt; 0 <span style="color: #000080;">Then</span>
      <span style="color: #008000;">' Convert Domain User SID to SDDL
</span>      WScript.Echo <span style="color: #800000;">&quot;Getting Sid for &quot;</span> &amp; UserName
      SDDL = ArraySidToStrSid(arrSID)
&nbsp;
      <span style="color: #008000;">' Stage Domain User Profile into Registry under HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList\%DomainUserSDDL%
</span>      ret = CreateAndLinkProfile(SDDL, arrSID, strProfile)
   <span style="color: #000080;">Else</span>
      <span style="color: #008000;">'Account didn't exist in the domain or ACL failed to set on Folder
</span>   <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>For the most part this function behaves by running external commands to mount registry hives, and set ACLs on folders and registry, all up until we call GetDomainUserSidFromFolderACL. This is where we retrieve the SID of the Domain User that we are pre-staging via the ACL we set earlier on the Local User Profile folder. This subverts the need to query Active Directory for the SID through other means.</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> GetDomainUserSidFromFolderACL(strFolder, strUserName, strUserDomain)
   <span style="color: #000080;">Dim</span> arrSID(0)
   GetDomainUserSidFromFolderACL = arrSID
&nbsp;
   <span style="color: #000080;">Set</span> objFSO = CreateObject(<span style="color: #800000;">&quot;Scripting.FileSystemObject&quot;</span>)
   <span style="color: #000080;">If</span> <span style="color: #000080;">Not</span> objFSO.FolderExists(strFolder) <span style="color: #000080;">Then</span>
      <span style="color: #000080;">Set</span> objFSO = <span style="color: #000080;">Nothing</span>
      <span style="color: #000080;">Exit</span> <span style="color: #000080;">Function</span>
   <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
&nbsp;
   <span style="color: #008000;">' Ensure that strFolder is of the form C:\\Documents and Settings\\UserName
</span>    strFolderName = Replace(strFolder, <span style="color: #800000;">&quot;\\&quot;</span>,<span style="color: #800000;">&quot;\&quot;</span>)
    strFolderName = Replace(strFolderName, <span style="color: #800000;">&quot;\&quot;</span>,<span style="color: #800000;">&quot;\\&quot;</span>)
&nbsp;
   <span style="color: #000080;">Set</span> wmiFileSecSetting = GetObject( _
      <span style="color: #800000;">&quot;winmgmts:Win32_LogicalFileSecuritySetting.path='&quot;</span> &amp; strFolderName &amp; <span style="color: #800000;">&quot;'&quot;</span>)
&nbsp;
   RetVal = wmiFileSecSetting. _
       GetSecurityDescriptor(wmiSecurityDescriptor)
   <span style="color: #000080;">If</span> Err &lt;&gt; 0 <span style="color: #000080;">Then</span>
       <span style="color: #000080;">Exit</span> <span style="color: #000080;">Function</span>
   <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
&nbsp;
   <span style="color: #008000;">' Retrieve the DACL array of Win32_ACE objects.
</span>   DACL = wmiSecurityDescriptor.DACL
&nbsp;
   <span style="color: #000080;">For</span> <span style="color: #000080;">each</span> wmiAce <span style="color: #000080;">in</span> DACL
   <span style="color: #008000;">' Get Win32_Trustee object from ACE 
</span>      <span style="color: #000080;">Set</span> Trustee = wmiAce.Trustee
      <span style="color: #000080;">If</span> (StrComp(Trustee.Name, strUserName, vbTextCompare) = 0) <span style="color: #000080;">And</span> _
         (StrComp(Trustee.Domain, strUserDomain, vbTextCompare) = 0) <span style="color: #000080;">Then</span>
         GetDomainUserSidFromFolderACL = Trustee.SID
         <span style="color: #000080;">Exit</span> <span style="color: #000080;">Function</span>
      <span style="color: #000080;">End</span> <span style="color: #000080;">If</span>
   <span style="color: #000080;">Next</span>
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>Although this subverts the need to Query Active Directory, this does also mean that we receive the SID in a format that is unexpected. Normally, via querying Active Directory we would have received a SID in an Octet String format. Querying the SID from WMI returned it in SDDL or String SID format. The format that we receive the SID from the ACL is in an Array of Integers. In order to Pre-stage an account we need the SDDL/String SID, and the only way to get this in VBScript is to manually convert it using some functions developed by Richard Mueller and Wilfred Wong in <a href="http://groups.google.com.au/group/microsoft.public.windows.server.active_directory/browse_thread/thread/5e26b20bba486280/95eb5a589be4cf11">this newsgroup posting</a>.</p>
<p>Instead of using only the code listed, we need to alter it for dealing with the SID array we received back from the ACL.</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> ArraySidToStrSid(arrSid)
   <span style="color: #008000;">' Function to convert OctetString (byte array) to Decimal string (SDDL) Sid.
</span>   <span style="color: #000080;">Dim</span> strHex, strDec
&nbsp;
   strHex = ArraySidToHexStr(arrSid)
   strDec = HexStrToDecStr(strHex)
   ArraySidToStrSid = strDec
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span>
&nbsp;
<span style="color: #000080;">Function</span> ArraySidToHexStr(arrSid)
   ArraySidToHexStr = <span style="color: #800000;">&quot;&quot;</span>
   <span style="color: #000080;">For</span> <span style="color: #000080;">Each</span> x <span style="color: #000080;">In</span> arrSid
      ArraySidToHexStr = ArraySidToHexStr &amp; _
         Right(<span style="color: #800000;">&quot;0&quot;</span> &amp; Hex(x), 2)
   <span style="color: #000080;">Next</span>
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>The HexStrToDecStr function is the same as it was from the <a href="http://groups.google.com.au/group/microsoft.public.windows.server.active_directory/browse_thread/thread/5e26b20bba486280/95eb5a589be4cf11">Richard Mueller posting</a> listed above.</p>
<p>Finally we just need to run through the actual staging of the account:</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> CreateAndLinkProfile(strNewSDDL, strNewSID, strProfilePath)
   WScript.Echo <span style="color: #800000;">&quot;Creating Profile for &quot;</span> &amp; strNewSDDL &amp; <span style="color: #800000;">&quot;: &quot;</span> &amp; strProfilePath
   <span style="color: #008000;">'Write Sid to registry
</span>   ret = WriteRegBinaryToRegistry(HKEY_LOCAL_MACHINE,<span style="color: #800000;">&quot;SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\&quot;</span> &amp; strNewSDDL,<span style="color: #800000;">&quot;Sid&quot;</span>,strNewSID)
   ret = WriteRegStringToRegistry(HKEY_LOCAL_MACHINE,<span style="color: #800000;">&quot;SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\&quot;</span> &amp; strNewSDDL,<span style="color: #800000;">&quot;ProfileImagePath&quot;</span>,strProfilePath)
   ret = WriteRegStringToRegistry(HKEY_LOCAL_MACHINE,<span style="color: #800000;">&quot;SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\&quot;</span> &amp; strNewSDDL,<span style="color: #800000;">&quot;CentralProfile&quot;</span>,<span style="color: #800000;">&quot;&quot;</span>)
   ret = WriteRegDwordToRegistry(HKEY_LOCAL_MACHINE,<span style="color: #800000;">&quot;SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\&quot;</span> &amp; strNewSDDL,<span style="color: #800000;">&quot;Flags&quot;</span>,1)
   ret = WriteRegDwordToRegistry(HKEY_LOCAL_MACHINE,<span style="color: #800000;">&quot;SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\&quot;</span> &amp; strNewSDDL,<span style="color: #800000;">&quot;State&quot;</span>,0)
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>At this point if the Domain User logs in they get redirected to the existing local users profile. Then if rollback is initiated they log on with the Local User account with the same profile. This is seamless to end users, both forward and backward. </p>
<p>On a side note the functions for writing to the registry are through WMI due to needing to write Binary values to the Registry</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #000080;">Function</span> WriteRegBinaryToRegistry(Hive, strKeyPath, strValueName, ArrValues)
   strComputer = <span style="color: #800000;">&quot;.&quot;</span>
   <span style="color: #000080;">Set</span> oReg = GetObject(<span style="color: #800000;">&quot;winmgmts:{impersonationLevel=impersonate}!\\&quot;</span> &amp; _
               strComputer &amp; <span style="color: #800000;">&quot;\root\default:StdRegProv&quot;</span>)
   oReg.CreateKey Hive,strKeyPath
&nbsp;
   oReg.SetBinaryValue Hive, strKeyPath, strValueName,ArrValues
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span>
&nbsp;
<span style="color: #000080;">Function</span> WriteRegDwordToRegistry(Hive, strKeyPath, strValueName, Value)
   strComputer = <span style="color: #800000;">&quot;.&quot;</span>
   <span style="color: #000080;">Set</span> oReg = GetObject(<span style="color: #800000;">&quot;winmgmts:{impersonationLevel=impersonate}!\\&quot;</span> &amp; _
               strComputer &amp; <span style="color: #800000;">&quot;\root\default:StdRegProv&quot;</span>)
   oReg.CreateKey Hive,strKeyPath
&nbsp;
   oReg.SetDwordValue Hive, strKeyPath, strValueName,Value
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span>
&nbsp;
<span style="color: #000080;">Function</span> WriteRegStringToRegistry(Hive, strKeyPath, strValueName, Value)
   strComputer = <span style="color: #800000;">&quot;.&quot;</span>
   <span style="color: #000080;">Set</span> oReg = GetObject(<span style="color: #800000;">&quot;winmgmts:{impersonationLevel=impersonate}!\\&quot;</span> &amp; _
               strComputer &amp; <span style="color: #800000;">&quot;\root\default:StdRegProv&quot;</span>)
   oReg.CreateKey Hive,strKeyPath
&nbsp;
   oReg.SetStringValue Hive, strKeyPath, strValueName,Value
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span></pre></div></div>

<p>Cheers, Chris.</p>
<p>Edit: <a href='http://www.dwarfsoft.com/blog/wp-content/uploads/2010/03/DomainAccountProfileStaging.vbs_.txt'>DomainAccountProfileStaging.vbs</a> has been uploaded as a complete file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dwarfsoft.com/blog/2010/03/15/shared-user-profiles-staging-scripts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>More GTD-PHP Work</title>
		<link>http://www.dwarfsoft.com/blog/2009/08/20/more-gtd-php-work/</link>
		<comments>http://www.dwarfsoft.com/blog/2009/08/20/more-gtd-php-work/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 05:53:44 +0000</pubDate>
		<dc:creator>dwarfsoft</dc:creator>
				<category><![CDATA[Authoring]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[Addon]]></category>
		<category><![CDATA[GTD]]></category>
		<category><![CDATA[Initiative]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[Theory]]></category>

		<guid isPermaLink="false">http://www.dwarfsoft.com/blog/?p=282</guid>
		<description><![CDATA[I have updated my GTD-PHP Email Import Addon so that it now integrates with the current Subversion revision of the code. There is one bug left in it, in that it will not check that there is a mail server set before it tries to connect. I find that this error occurs the first time [...]]]></description>
			<content:encoded><![CDATA[<p>I have updated my GTD-PHP Email Import Addon so that it now integrates with the current Subversion revision of the code. There is one bug left in it, in that it will not check that there is a mail server set before it tries to connect. I find that this error occurs the first time the session is established with the server, and from then on it works fine. By performing an error check against $server = &#8220;&#8221; I should be able to remove that bug as well. </p>
<p>The updated <a href="http://www.gtd-php.com/Developers/EmailImport">EmailImport</a> Addon is now available for download from the <a href="https://www.hosted-projects.com/trac/toae/gtdphp/ticket/569">GTD-PHP Trac wiki</A>.</p>
<p><span id="more-282"></span></p>
<p>I have since moved on to the next most important feature on my personal list of Enhancements (yes, before I fix my known bug in the previous one). I want to be able to have a scheduled email sent every morning with a report on what Actions are overdue, what actions are due today and a rundown on the coming actions in the next week. Additionally this report should contain information on Project deadlines of note (overdue, due and coming). Another report I want is to be able to have the weekly review report emailed weekly to myself (at my work and home email addresses).</p>
<p>To achieve this I have been looking in to using php scripts to create cron jobs on the host system (or schtasks jobs if on a WAMP server for example). I have most of the information required to achieve this now. Once I have implemented a scheduled tasks manager from within GTD-PHP I will then build a custom report builder, which will then be enhanced by the emailer. In all, three addons become interlocked for completing this next feature.</p>
<p>If I didn&#8217;t have GTD-PHP (and therefore wasn&#8217;t following the GTD methodology) to manage all my projects I probably would not be in the position of even being capable of extending any project (I am busier now than ever, but I have more control over my time than ever before). By completing the Addons in my list I will have so much better control over my time and be in a perfect position to achieve some Zen in my life <img src='http://www.dwarfsoft.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Just so you get some perspective, when I first set up GTD-PHP I added a lot of actions, and immediately closed them. Those statistics had me max at about 30 items in a week. Currently this week I have closed 75 items, and the week isn&#8217;t over. Most of these items have been self imposed actions for me to develop, research, repair, investigate, or whatever. I have given myself more work than at the start, and I have more time off now to blog about it (yet another action) than I have ever had previously.</p>
<p>I thoroughly encourage everybody to look into David Allens Getting Things Done. Worked wonders for me <img src='http://www.dwarfsoft.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Cheers, Chris.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dwarfsoft.com/blog/2009/08/20/more-gtd-php-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updated GTD-PHP POP3 Inbox Import</title>
		<link>http://www.dwarfsoft.com/blog/2009/08/04/updated-gtd-php-pop3-inbox-import/</link>
		<comments>http://www.dwarfsoft.com/blog/2009/08/04/updated-gtd-php-pop3-inbox-import/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 01:39:09 +0000</pubDate>
		<dc:creator>dwarfsoft</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Addon]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[Groupwise]]></category>
		<category><![CDATA[GTD]]></category>
		<category><![CDATA[Home]]></category>
		<category><![CDATA[Import]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[POP3]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://www.dwarfsoft.com/blog/2009/08/04/updated-gtd-php-pop3-inbox-import/</guid>
		<description><![CDATA[So I have been using the new script this morning, and testing adding new actions from the GroupWise account at work. Here is where I encountered some issues.
GroupWise decides it wants to MIME Encode the email, which brings about my first problem. I need to account for multiple MIME Parts. After resolving this my next [...]]]></description>
			<content:encoded><![CDATA[<p>So I have been using the new script this morning, and testing adding new actions from the GroupWise account at work. Here is where I encountered some issues.</p>
<p>GroupWise decides it wants to MIME Encode the email, which brings about my first problem. I need to account for multiple MIME Parts. After resolving this my next issue is that the corporate email gateway decides to append a massive disclaimer at the bottom of the email, bloating my item by at least 1000%. So I implemented the ability to cut out disclaimers based on a stripos call. I can have a list of different filters here and it will cut them all out.</p>
<p>After fixing this up and resolving the functional issues I <a href="https://www.hosted-projects.com/trac/toae/gtdphp/ticket/569">logged this addon as a ticket</A> in the <a href="https://www.hosted-projects.com/trac/toae/gtdphp/">GTD-PHP Trac</a> system.</p>
<p><span id="more-279"></span></p>
<p>I have a few further updates to make, including having bulk uploads, custom tags and mail filters.</p>
<p>Cheers, Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dwarfsoft.com/blog/2009/08/04/updated-gtd-php-pop3-inbox-import/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GTD-PHP Import from POP3 Mail</title>
		<link>http://www.dwarfsoft.com/blog/2009/08/04/gtd-php-import-from-pop3-mail/</link>
		<comments>http://www.dwarfsoft.com/blog/2009/08/04/gtd-php-import-from-pop3-mail/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 21:00:28 +0000</pubDate>
		<dc:creator>dwarfsoft</dc:creator>
				<category><![CDATA[Home]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[Addon]]></category>
		<category><![CDATA[GTD]]></category>
		<category><![CDATA[Import]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Script]]></category>

		<guid isPermaLink="false">http://www.dwarfsoft.com/blog/2009/08/04/gtd-php-import-from-pop3-mail/</guid>
		<description><![CDATA[I have been attempting to get a fully working system set up for David Allens Getting Things Done. To this end I have set up an install of GTD-PHP. 
Being the kind of person who likes to adapt, change, and implement better solutions, particularly for myself, I created a list of features I would like [...]]]></description>
			<content:encoded><![CDATA[<p>I have been attempting to get a fully working system set up for <a href="http://www.davidco.com/">David Allens</a> Getting Things Done. To this end I have set up an install of <a href="http://www.gtd-php.com/">GTD-PHP</a>. </p>
<p>Being the kind of person who likes to adapt, change, and implement better solutions, particularly for myself, I created a list of features I would like to see in my GTD-PHP installation. One of the first problems I had with the existing system was that it does not support importing Inbox items from a real mail Inbox.</p>
<p>I did some research and came across an <a href="https://www.hosted-projects.com/trac/toae/gtdphp/attachment/ticket/558/mail.php.src">existing mail importer</a>, however this required directly piping mail from SMTP into the php script, which I could not do on my host (or would prefer not to do).</p>
<p><span id="more-274"></span></p>
<p>I decided to build my own POP3 Importer of Inbox items and decided to learn PHP and <a href="http://uk2.php.net/imap_open">imap_open</a>. I built it as an addon to GTD-PHP that could be called to do an import, however I am still going to extend it so that in the GTD-PHP header additional headers can be called (ones that identify if new items have been added to an Inbox so I can get feedback of when somebody mails into that account).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">//Script to insert e-mails into GTD-PHP inbox.</span>
<span style="color: #666666; font-style: italic;">//These are loaded from a pop3 account</span>
<span style="color: #666666; font-style: italic;">//The account info and other options are configured in the config.php file</span>
<span style="color: #666666; font-style: italic;">//$config['addons']['pop3inbox']=array(</span>
<span style="color: #666666; font-style: italic;">//        &quot;link&quot;=&gt;&quot;addons/pop3inbox/import.php&quot;,</span>
<span style="color: #666666; font-style: italic;">//        'title'=&gt;&quot;Import POP3 Mail&quot;, 'label'=&gt;&quot;Import Inbox&quot;,</span>
<span style="color: #666666; font-style: italic;">//        'where'=&gt;'item.php?type=i','when'=&gt;'after',</span>
<span style="color: #666666; font-style: italic;">//        'options'=&gt;array(&quot;user&quot;   =&gt; 'gtduser',</span>
<span style="color: #666666; font-style: italic;">//                         &quot;pass&quot;   =&gt; 'gtdpass',</span>
<span style="color: #666666; font-style: italic;">//                         &quot;server&quot; =&gt; 'mail.server.com',</span>
<span style="color: #666666; font-style: italic;">//                         &quot;port&quot;   =&gt; '995',</span>
<span style="color: #666666; font-style: italic;">//                         &quot;type&quot;   =&gt; '/pop3/ssl/novalidate-cert',</span>
<span style="color: #666666; font-style: italic;">//                         &quot;delete&quot; =&gt; true)</span>
<span style="color: #666666; font-style: italic;">//                         );</span>
<span style="color: #666666; font-style: italic;">//Subject becomes title</span>
<span style="color: #666666; font-style: italic;">//From &amp; Body becomes description</span>
<span style="color: #000088;">$title</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'Import POP3 Inbox'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">include_once</span> <span style="color: #0000ff;">'header.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$msoptions</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$addon</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'options'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'host'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'user'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'pass'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$imap</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imap_open</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;{&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$msoptions</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'server'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;:&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$msoptions</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'port'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #000088;">$msoptions</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'type'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;}INBOX&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$msoptions</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'user'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$msoptions</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'pass'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$imap</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">imap_errors</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$num_msg</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imap_num_msg</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$imap</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">include_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'gtdfuncs.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
  <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;importing &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$num_msg</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot; messages&lt;br&gt;&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;div class='success'&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$num_msg</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">--</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// empty vars</span>
    <span style="color: #000088;">$from</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$subject</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$headers</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$message</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$header</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imap_headerinfo</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$imap</span><span style="color: #339933;">,</span> <span style="color: #000088;">$i</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">80</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">80</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$from</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$header</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fromaddress</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$subject</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$header</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchsubject</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$date</span>    <span style="color: #339933;">=</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'YmdHis'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$header</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">udate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$message</span><span style="color: #339933;">=</span><span style="color: #990000;">imap_body</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$imap</span><span style="color: #339933;">,</span> <span style="color: #000088;">$i</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$message</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;From: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$from</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$message</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO `&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'prefix'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;items` ( `itemId` , `title` , `description` , `desiredOutcome` )VALUES (NULL , '<span style="color: #006699; font-weight: bold;">$subject</span>', '<span style="color: #006699; font-weight: bold;">$message</span>', NULL);&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO `&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'prefix'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;itemstatus` (`itemId`, `dateCreated`, `lastModified`, `dateCompleted`) VALUES (NULL, '&quot;</span><span style="color: #339933;">.</span><span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;datemask&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;', NOW(), NULL);&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO `&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'prefix'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;itemattributes` ( `itemId` , `type` , `isSomeday` , `categoryId` , `contextId` , `timeframeId` , `deadline` , `repeat` , `suppress` , `suppressUntil` )VALUES (NULL , 'i', 'n', '0', '0', '0', NULL , '0', 'n', NULL);&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Imported '&quot;</span><span style="color: #339933;">.</span><span style="color: #990000;">stripslashes</span><span style="color: #009900;">&#40;</span>escapeChars<span style="color: #009900;">&#40;</span><span style="color: #000088;">$subject</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;' into Inbox&lt;br /&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$msoptions</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'delete'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #990000;">imap_delete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$imap</span><span style="color: #339933;">,</span> <span style="color: #000088;">$i</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;/div&gt;&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$msoptions</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'delete'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #990000;">imap_expunge</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$imap</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">imap_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$imap</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">include_once</span> <span style="color: #0000ff;">'footer.php'</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Works pretty well at this point. Though I am having problems getting mail into that POP3 account. Will have to work further on that today <img src='http://www.dwarfsoft.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Cheers, Chris.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dwarfsoft.com/blog/2009/08/04/gtd-php-import-from-pop3-mail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GroupWise Audit and Batch/Cmd Escaping</title>
		<link>http://www.dwarfsoft.com/blog/2009/07/27/groupwise-audit-and-batchcmd-escaping/</link>
		<comments>http://www.dwarfsoft.com/blog/2009/07/27/groupwise-audit-and-batchcmd-escaping/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 04:52:37 +0000</pubDate>
		<dc:creator>dwarfsoft</dc:creator>
				<category><![CDATA[Novell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[Batch]]></category>
		<category><![CDATA[CMD]]></category>
		<category><![CDATA[Groupwise]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[Strings]]></category>

		<guid isPermaLink="false">http://www.dwarfsoft.com/blog/?p=259</guid>
		<description><![CDATA[I was required recently to audit passwords on all the Novell GroupWise accounts in the cluster. This was not too much of a problem using existing solutions, except that all the existing solutions limited searches to either Users, or to objects with the &#8220;NGW: Object ID&#8221; attribute.
The Solutions I found include Check GroupWise Users for [...]]]></description>
			<content:encoded><![CDATA[<p>I was required recently to audit passwords on all the Novell GroupWise accounts in the cluster. This was not too much of a problem using existing solutions, except that all the existing solutions limited searches to either Users, or to objects with the &#8220;NGW: Object ID&#8221; attribute.</p>
<p>The Solutions I found include <a href="http://www.novell.com/coolsolutions/tools/17221.html">Check GroupWise Users for Password &#8211; Batch</a> and <a href="http://www.novell.com/communities/node/5753/check-groupwise-users-password">Check GroupWise Users for Password &#8211; Exe</a>, both of which made use of <a href="http://www.novell.com/coolsolutions/tools/13913.html">GWSend</a>. Being an avid scripting aficionado myself I opted for the first, so I could make changes.</p>
<p>First step was to export all User Objects with NGW: Object ID into an Excel sheet using <a href="http://www.novell.com/coolsolutions/tools/13908.html">DSReport</a>. Then export all GroupWise External Entities with NGW: Object ID to a different Excel Sheet. Finally I needed to export all GroupWise Resources, which do not have an NGW: Object ID, but their CN is effectively the NGW: Object ID for which we can log in and try to send emails. Upon completing this I compiled a single list of Allusers.csv which had the NGW: ObjectID/CN in the first column, and the DN for the Object Name and Location within the tree. This makes it far easier to track down the location of generic accounts (Something that none of the scripts account for).</p>
<p><span id="more-259"></span></p>
<p>So, my first run through the script ended in Fail. Apparently the above solutions are expecting Email Addresses without Spaces. So after fixing that up I run it again, and again hit a Fail. Apparently the above solutions fail to account for special characters (/ in this instance). So, I fix this up as well&#8230; My script runs, I get a report, then I realise that I have more results than original users. Apparently the above script also assumes that there is only 1 line in the result.txt file. So I modified the script to only print out a result once all lines of the result.txt file had been parsed, using a SET to determine if the &#8220;Error:&#8221; had been encountered or not (Error indicating that a Password is on the account, no Error indicating that there is No password).</p>
<p>So, now I run through and notice that the audit fails to log the full line of text, even though it is capable of actually running the audit against that account. Fortunately none of the accounts without passwords were affected by this, but I decided to fix this for future runs. To break down the issues I needed to fix into a list here is the summary:</p>
<ol>
<li>We have spaces in our Email Account Names</li>
<li>We have /&#8217;s in our Email Account Names</li>
<li>We have &amp;&#8217;s in our Email Account Names</li>
<li>We are trying to create a HTML file with the above special characters (specifically &amp;)</li>
<li>&amp; doesn&#8217;t tend to work too nicely in batch files when using an open Echo (tries to run everything after the &amp; as a program</li>
<li>I wanted to be able to track back to objects (DN&#8217;s) as opposed to just the GroupWise Account Name</li>
</ol>
<p>Spaces were easy to fix&#8230; When running the command against an account simply put the &#8220;account in quotes&#8221;. The next step is to handle the Email and DN objects as Strings within Quotes as well, but we don&#8217;t want to output the quotes, which means we need to handle them properly. Examine the following issue:</p>

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;">SET <span style="color: #0080FF; font-weight: bold;">String</span>=A <span style="color: #0080FF; font-weight: bold;">String</span> With Special Chars<span style="color: #66cc66;">&amp;</span>Slashes<span style="color: #66cc66;">/</span> <span style="color: #800080;">In</span> \ it<span style="color: #66cc66;">^</span> OK
ECHO <span style="color: #66cc66;">%</span>String<span style="color: #66cc66;">%</span></pre></div></div>

<p>This will return &#8220;&#8216;Slashes&#8217; is not recognized as an internal or external command, operable program or batch file.&#8221; Also, if we try and escape each of the characters we run into issues too.</p>

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;">SET <span style="color: #0080FF; font-weight: bold;">String</span>=A <span style="color: #0080FF; font-weight: bold;">String</span> With Special Chars<span style="color: #66cc66;">&amp;</span>Slashes<span style="color: #66cc66;">/</span> <span style="color: #800080;">In</span> \ it<span style="color: #66cc66;">^</span> OK
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:^=^^%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:\=^\%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:/=^/%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:&amp;=^&amp;%</span>
ECHO <span style="color: #66cc66;">%</span>String<span style="color: #66cc66;">%</span></pre></div></div>

<p>The Output ends up as &#8220;A String With Special Chars&#8221;. So, in order to fix this we need to handle the string within Quotes, and only output it at the end:</p>

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;">SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #ff0000;">&quot;A String With Special Chars&amp;Slashes/ In \ it^ OK&quot;</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:^=^^%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:\=^\%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:/=^/%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:&amp;=^&amp;%</span>
ECHO <span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:~1,-1%</span></pre></div></div>

<p>Finally, our output is &#8220;A String With Special Chars&amp;Slashes/ In \ it^ OK&#8221;, without the quotes. So the first part works now for my output to the Logs (although my logs are CSV so I tend to leave the quotes on just in case there is a lurking comma, but this does provide a pretty Output to the Console). Now we need to convert these for HTML output.</p>

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;">SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:^&amp;=^&amp;amp;%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:&lt;=^&amp;lt;%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:&gt;=^&amp;gt;%</span>
ECHO <span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:~1,-1%</span></pre></div></div>

<p>Just provides that little added extra safety net for an echo directly into a HTML log. I am annoyed that I didn&#8217;t manage to figure this out earlier as I had some scripts I went directly to VBScript for to avoid the &amp; errors I was getting. I had no idea that it was my subsequent SET x=%x:a=b%, SET x=%x:c=d% calls on an unquoted string.</p>
<p>The one caveat I have found to this is fixing quote marks within a string. I have yet to find a way to strip them effectively without breaking the string/batch file in the process. The closest I have come will work in most situations, but requires a placeholder you have to be sure will never exist within your string:</p>

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;">SET <span style="color: #0080FF; font-weight: bold;">String</span>=Thi\s<span style="color: #ff0000;">&quot; is ^a &amp;t&quot;</span>es<span style="color: #66cc66;">/</span>t
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #ff0000;">&quot;%String:&quot;</span>=<span style="color: #66cc66;">&amp;</span>quot<span style="color: #008000; font-style: italic;">;%&quot;</span>
Set <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:^=^^%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:&amp;=^&amp;%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:/=^/%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:\=^\%</span>
SET <span style="color: #0080FF; font-weight: bold;">String</span>=<span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:&amp;quot;=^&quot;%</span>
ECHO <span style="color: #66cc66;">%</span><span style="color: #0080FF; font-weight: bold;">String</span><span style="color: #FF1010; font-weight: bold;">:~1,-1%</span></pre></div></div>

<p>One other note I&#8217;d like to add is that of Padding numbers. This is a fairly well known feature of WinBatch, but I found it useful for getting well aligned output for which record I was currently up to:</p>

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;">Set _Num=<span style="color: #cc66cc;">0</span>
...
SET <span style="color: #66cc66;">/</span>A <span style="color: #66cc66;">%</span>_Num<span style="color: #66cc66;">%</span>=<span style="color: #66cc66;">%</span>_Num<span style="color: #66cc66;">%+</span><span style="color: #cc66cc;">1</span>
SET DispNum=     <span style="color: #66cc66;">%</span>_Num<span style="color: #66cc66;">%</span>
Echo <span style="color: #66cc66;">%</span>DispNum<span style="color: #FF1010; font-weight: bold;">:~-4%</span></pre></div></div>

<p>This pads the leading digits with spaces and specifies that I want a 4 character long string returned for the end of the string. (so &#8221;   1&#8243; in the first instance but in my case up to &#8221; 900&#8243; or  &#8220;9091&#8243;).</p>
<p>Hope this adds a little food for thought.</p>
<p>Cheers, Chris.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dwarfsoft.com/blog/2009/07/27/groupwise-audit-and-batchcmd-escaping/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Return to GetVolumeNumber</title>
		<link>http://www.dwarfsoft.com/blog/2008/09/02/return-to-getvolumenumber/</link>
		<comments>http://www.dwarfsoft.com/blog/2008/09/02/return-to-getvolumenumber/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 13:30:47 +0000</pubDate>
		<dc:creator>dwarfsoft</dc:creator>
				<category><![CDATA[Novell]]></category>
		<category><![CDATA[Politics]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Study]]></category>
		<category><![CDATA[Training]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[Auto Store]]></category>
		<category><![CDATA[AutoStore]]></category>
		<category><![CDATA[Mount]]></category>
		<category><![CDATA[Mount Points]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[VBScript]]></category>
		<category><![CDATA[Volume]]></category>

		<guid isPermaLink="false">http://www.dwarfsoft.com/blog/?p=62</guid>
		<description><![CDATA[Since my last post I came to the realisation that I really didn&#8217;t like the way that the Diskpart box popped up on screen during the function call, so I did what I said I should have done and created the function the other way. This also cleans up the text files after completion, which [...]]]></description>
			<content:encoded><![CDATA[<p>Since my last post I came to the realisation that I really didn&#8217;t like the way that the Diskpart box popped up on screen during the function call, so I did what I said I should have done and created the function the other way. This also cleans up the text files after completion, which is something the previous function didn&#8217;t do.</p>
<p>For completeness I also made the function a little more generic, so it takes the Volume Label as the Variable, and falls back to &#8220;IMAGE&#8221; if none was passed.</p>
<p><span id="more-62"></span></p>

<div class="wp_syntax"><div class="code"><pre class="vbnet" style="font-family:monospace;"><span style="color: #0600FF;">Function</span> GetVolumeNumberHidden<span style="color: #000000;">&#40;</span>Label<span style="color: #000000;">&#41;</span>
   <span style="color: #FF8000;">On</span> <span style="color: #FF8000;">Error</span> <span style="color: #FF8000;">Resume</span> <span style="color: #FF8000;">Next</span>
   <span style="color: #0600FF;">Const</span> <span style="color: #0600FF;">ForWriting</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">2</span>
   <span style="color: #0600FF;">Const</span> <span style="color: #0600FF;">ForReading</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span>
&nbsp;
   <span style="color: #0600FF;">If</span> Label<span style="color: #008000;">=</span><span style="color: #808080;">&quot;&quot;</span> <span style="color: #FF8000;">Then</span>
      Label<span style="color: #008000;">=</span><span style="color: #808080;">&quot;IMAGE&quot;</span>
   <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
&nbsp;
   <span style="color: #FF8000;">Set</span> oShell <span style="color: #008000;">=</span> <span style="color: #0600FF;">CreateObject</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;WScript.Shell&quot;</span><span style="color: #000000;">&#41;</span>
&nbsp;
   <span style="color: #FF8000;">Set</span> oFSO <span style="color: #008000;">=</span> <span style="color: #0600FF;">CreateObject</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;Scripting.FileSystemObject&quot;</span><span style="color: #000000;">&#41;</span>
   TempFile <span style="color: #008000;">=</span> oShell.<span style="color: #0000FF;">ExpandEnvironmentStrings</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;C:\Temp\dp.txt&quot;</span><span style="color: #000000;">&#41;</span>
   ListFile <span style="color: #008000;">=</span> oShell.<span style="color: #0000FF;">ExpandEnvironmentStrings</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;C:\Temp\dl.txt&quot;</span><span style="color: #000000;">&#41;</span>
   <span style="color: #FF8000;">Set</span> oFile <span style="color: #008000;">=</span> oFSO.<span style="color: #0000FF;">OpenTextFile</span><span style="color: #000000;">&#40;</span>TempFile,<span style="color: #0600FF;">ForWriting</span>,<span style="color: #0600FF;">True</span><span style="color: #000000;">&#41;</span>
&nbsp;
   oFile.<span style="color: #0000FF;">WriteLine</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;LIST VOLUME&quot;</span><span style="color: #000000;">&#41;</span>
   oFile.<span style="color: #0600FF;">Close</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
   oShell.<span style="color: #0000FF;">Run</span> <span style="color: #808080;">&quot;%comspec% /c diskpart /s &quot;</span> <span style="color: #008000;">&amp;</span>amp; TempFile <span style="color: #008000;">&amp;</span>amp; _
      <span style="color: #808080;">&quot; &amp;gt; &quot;</span> <span style="color: #008000;">&amp;</span>amp; ListFile, <span style="color: #FF0000;">0</span>, <span style="color: #0600FF;">True</span>
&nbsp;
   Ouptut <span style="color: #008000;">=</span> <span style="color: #808080;">&quot;&quot;</span>
   <span style="color: #0600FF;">Str</span> <span style="color: #008000;">=</span> <span style="color: #808080;">&quot;&quot;</span>
&nbsp;
   <span style="color: #FF8000;">Set</span> oFile <span style="color: #008000;">=</span> oFSO.<span style="color: #0000FF;">OpenTextFile</span><span style="color: #000000;">&#40;</span>ListFile,<span style="color: #0600FF;">ForReading</span><span style="color: #000000;">&#41;</span>
&nbsp;
   <span style="color: #0600FF;">Do</span> until oFile.<span style="color: #0000FF;">AtEndOfStream</span>
      <span style="color: #0600FF;">Str</span> <span style="color: #008000;">=</span> oFile.<span style="color: #0000FF;">ReadLine</span>
      <span style="color: #0600FF;">If</span> <span style="color: #0600FF;">InStr</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">Str</span>,<span style="color: #808080;">&quot;Volume&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">&amp;</span>gt; <span style="color: #FF0000;">0</span> <span style="color: #FF8000;">Then</span>
         <span style="color: #0600FF;">If</span> <span style="color: #804040;">Not</span> <span style="color: #000000;">&#40;</span><span style="color: #FF8000;">Mid</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">Str</span>,<span style="color: #FF0000;">10</span>,<span style="color: #FF0000;">3</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=</span> <span style="color: #808080;">&quot;###&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">Then</span>
            DriveLetter <span style="color: #008000;">=</span> <span style="color: #FF8000;">Mid</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">Str</span>,<span style="color: #FF0000;">16</span>,<span style="color: #FF0000;">1</span><span style="color: #000000;">&#41;</span>
            VolumeNumber <span style="color: #008000;">=</span> <span style="color: #0600FF;">Trim</span><span style="color: #000000;">&#40;</span><span style="color: #FF8000;">Mid</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">Str</span>,<span style="color: #FF0000;">10</span>,<span style="color: #FF0000;">3</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
            <span style="color: #0600FF;">If</span> <span style="color: #0600FF;">StrComp</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">Trim</span><span style="color: #000000;">&#40;</span><span style="color: #FF8000;">Mid</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">Str</span>,<span style="color: #FF0000;">20</span>,<span style="color: #FF0000;">12</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>,<span style="color: #0600FF;">Trim</span><span style="color: #000000;">&#40;</span>Label<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">=</span><span style="color: #FF0000;">0</span> <span style="color: #FF8000;">Then</span>
               GetVolumeNumberHidden <span style="color: #008000;">=</span> VolumeNumber
&nbsp;
               oFile.<span style="color: #0600FF;">Close</span>
               <span style="color: #0600FF;">If</span> oFSO.<span style="color: #0000FF;">FileExists</span><span style="color: #000000;">&#40;</span>TempFile<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">Then</span>
                  oFSO.<span style="color: #0000FF;">DeleteFile</span> TempFile, <span style="color: #0600FF;">True</span>
               <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
               <span style="color: #0600FF;">If</span> oFSO.<span style="color: #0000FF;">FileExists</span><span style="color: #000000;">&#40;</span>ListFile<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">Then</span>
                  oFSO.<span style="color: #0000FF;">DeleteFile</span> ListFile, <span style="color: #0600FF;">True</span>
               <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
&nbsp;
               <span style="color: #0600FF;">Exit</span> <span style="color: #0600FF;">Function</span>
            <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
         <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
      <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
   <span style="color: #0600FF;">Loop</span>
&nbsp;
   oFile.<span style="color: #0600FF;">Close</span>
   <span style="color: #0600FF;">If</span> oFSO.<span style="color: #0000FF;">FileExists</span><span style="color: #000000;">&#40;</span>TempFile<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">Then</span>
      oFSO.<span style="color: #0000FF;">DeleteFile</span> TempFile, <span style="color: #0600FF;">True</span>
   <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
   <span style="color: #0600FF;">If</span> oFSO.<span style="color: #0000FF;">FileExists</span><span style="color: #000000;">&#40;</span>ListFile<span style="color: #000000;">&#41;</span> <span style="color: #FF8000;">Then</span>
      oFSO.<span style="color: #0000FF;">DeleteFile</span> ListFile, <span style="color: #0600FF;">True</span>
   <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">If</span>
<span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Function</span></pre></div></div>

</p>
<p>This function now makes its way into the Completed stage and now I move on to other things. I have been working very frantically on my AutoStore script. This function is used in both the Store/Restore installation, and the AutoStore script itself, in order to get the timestamp of the previously stored image files. Some of the other fun things I have been playing with involve Novell Workstation Policy Packages, and Package Schedules. In order to initiate the AutoStore process I have created an array of Package Schedules that calls my AutoImage.vbe file. I noticed that during the process of Installation, the MSI had not completed before the AutoImage.vbe file was attempted to be run. This lead to a WScript error because the target file did not exist. I modified the run information to the following:</p>

<div class="wp_syntax"><div class="code"><pre class="winbat" style="font-family:monospace;">C:\Windows\System32\cmd.exe /c &quot;if exist (
   C:\SOE\AUTOSTORE\AutoImage.vbe) (
      start wscript C:\SOE\AUTOSTORE\AutoImage.vbe Interval=14 Force )&quot;</pre></div></div>

<p>At first glance it may seem that some of this can be discarded, however it is all required. In order to first check that the file exists without requiring ANY script to have been installed onto the target machine we need to use &#8220;<strong>if exist</strong>&#8221; which requires running through cmd.exe because it is a command interpreter command, not a stand alone executable. If we do not use <strong>Start</strong> then the command screen stays open while the script runs, or while a popup box explaining to users that they need to reboot is displayed. This appears a disjointed visually and lead to me wanting to close all those blank black windows. WScript does not explicitly need to be called, but since I want to specify WScript instead of CScript I have included it for completeness sake.</p>
<p>In order that the command window does not show up for most of the background calls to the script I have ensured that it runs in the SYSTEM security space. The Unsecure System space is used only for those functions where the script requires user input or provides user feedback. This limits the interruption to the general use of the PCs.</p>
<p>I spent much of the past few days creating and modifying the scripts, and I spent all afternoon packaging the script into the MSI and creating the Policy Packages. I have also now documented the Policy Package creation process and documented the usage of the script. Hopefully I can get it all slapped together and rolled out, as we need to force a store before Monday, when an updated software package is being forced out. I have to love the communication we get prior to these things. I have had to kill myself to get the modifications done to their current point, and as yet they are untested for machines which have not received some of the custom modifications we have implemented. All will come to light tomorrow.</p>
<p>Cheers, Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dwarfsoft.com/blog/2008/09/02/return-to-getvolumenumber/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
