TofuBug

Member
  • Content count

    33
  • Joined

  • Last visited

Community Reputation

0 Neutral

About TofuBug

  • Birthday 01/29/1978

Contact Methods

  • AIM
    tofubug27
  • MSN
    tofubug24@yahoo.com
  • Yahoo
    tofubug24
  1. Hello Everyone!, I've got one small but infuriating issue with my custom USMT XML files. Our organization is all XP but we are using the USMT 3.00 In a nut shell I have a profile backup HTA i've written that lets you pick Data, Settings, or Both and uses the USMT to back up the logged on users profile data and settings. Basically to give all of our Power User's the ability to run a quick backup and/or restore on their profile only since most backup software needs admin rights to really function well if at all in some cases (Thanks a lot Acronis) Everything is working just fine have all the tweaks i want but for some reason it refuses to migrate Empty folders Here's an excerpt from my custom LPMigUser.xml file to migrate the Desktop folder <!-- This component migrates Desktop files --> <component type="Documents" context="User"> <displayName>Desktop</displayName> <paths> <path type="File">%CSIDL_DESKTOP%</path> </paths> <role role="Data"> <rules> <include> <objectSet> <pattern type="File">%CSIDL_DESKTOP%\* [*]</pattern> </objectSet> </include> <merge script="MigXmlHelper.DestinationPriority()"> <objectSet> <pattern type="File">%CSIDL_DESKTOP% [desktop.ini]</pattern> </objectSet> </merge> <merge script="MigXmlHelper.SourcePriority()"> <objectSet> <pattern type="File">%CSIDL_DESKTOP%\* [*]</pattern> </objectSet> </merge> </rules> </role> </component> Now according to MS's documentation the line <pattern type="File">%CSIDL_DESKTOP%\*\[*]</pattern> Should migrate all the files AND all the sub folders AND all the files in said sub folders etc. However when i run it if i have for instance the following folder tree Desktop Empty Folder Folder with File Some File.txt when the scanstate is done out where scanstate puts all the captured folder and files the Folder with File folder will be there but the Empty Folder folder will not. WHY? that's all i want to know Ok I lied I also want to know HOW do i make it capture the empty sub folders Any help is appreciated Cheers,
  2. Justin Can't really tell you what specifically is causing this since i'm not going to ask you what DC's you are using and what User Name and password you are using but I'm assuming you know what one of your domain controllers are and the domain you are on and have a user name and password with at the lest read access to the LDAP protocol Let me put out an example semi stolen from MS's technet examples say your domain is RVB.US.COM Say your domain controllers are RVB_DC1, RVB_DC2 and RVB_DC3 Now say you have a logon of SARGE with a password of D1rtb@g your code from above would look like this Set Domain = GetObject("LDAP:").OpenDSObject("LDAP://RVB_DC2/DC=RVB,DC=US,DC=Com","RVB\SARGE","D1rtb@g",1 + 512) or this Set Domain = GetObject("LDAP:").OpenDSObject("LDAP://RVB_DC1/DC=RVB,DC=US,DC=Com","RVB\SARGE","D1rtb@g",1 + 512) or this Set Domain = GetObject("LDAP:").OpenDSObject("LDAP://RVB_DC3/DC=RVB,DC=US,DC=Com","RVB\SARGE","D1rtb@g",1 + 512) The one thing I've found people i work with for this stuff forget is that every section of text seperated by a . or the beginning or end of the domain has to have its own DC= Other than that it might be the account does not have permissions on the server or the plugin did not work i would try the same code on a windows system that you know you can get to AD manually with the ADSI Administrative tools or some third party software I use Softerra's LDAP Browser 2.6 because unlike MS's admin tool kit it lists everything as a details list view which if you know what you are looking for makes it faster to get to things than the tabbed approach does. Anyway hope that helps a little Cheers
  3. Quick Question to see if anyone has any ideas how to fix this I'm trying to get embedded zip files to open from word 2003 professional SP3 when i double click the files i get an error This object was created in Package. This application is not available to open this object. Make sure the application is properly installed and that it has not been deleted, moved or renamed now if i try and create a blank word doc go to insert->object then from file with display as icon if i choose a zip file it adds it with packager just fine but as soon as i double click the icon in my doc i get the same error. Not sure what's going on here i'm running winzip 9 SR1 full corporate version, I've tried this with office 2003 sp2, sp3, without winzip with newer winzip always the same. however if i drag and drop the zip file into word it works Also if i use send to compressed folder and embed the zip file that creates it works as well Any help will be greatly appreciated
  4. It's not so much that I like typing just my fingers tend to ramble on and on (usually because they're trying to play catch-up to my thought process) I just need fingers that have the same reaction time as oh say a synapse firing. And Yes Yes it is.
  5. Everyone, Quick question. Has ANYONE gotten HTML Components to work in PE 2.0 I have HTA support turned on in the boot.wim along with scripting, mdac, xml, wmi I am currently running a simple HTA for our imaging technicians that loads as part of PE (works great) However most of the HTA tools I have developed for use in our normal operating environment are comprised of multiple HTML Components One component for instance is Logon.htc Nothing really fancy about it, when visible it provides the user a Username textbox and a Password textbox along with a logon button and Cancel button It has exposed methods to allow the component to be hidden or shown, it internally handles the actual Username and Password validation by bouncing off of AD using LDAP's OpenDSObject method finally it alerts its parent document of the success or failure of the logon attempt through 2 custom events onSuccessfulLogon and onUnsuccessfulLogon the Username and Password can be retrieved or changed using scripting for a userless interaction with the component as well Here's logon.htc to give you an idea what I mean <public:component lightWeight="True" tagname="Logon"> <public:method name="ShowLogon" /> <public:property name="UserID" get="GetUserID" put="PutUserID" /> <public:property name="Password" get="GetPassword" put="GetPassword" /> <Public:event name="onSuccessfullLogon" id="SuccessfullLogonEventID" /> <public:event name="onUnsuccessfullLogon" id="UnsuccessfullEventID" /> </public:component> <script language="vbscript" type="text/vbscript"> On Error Resume Next '----------------------Component HTML objects---------------------- Dim LogonTitleText Dim UserNameText Dim UserNameValueText Dim PasswordText Dim PasswordValueText Dim OkButton Dim CancelButton '-----------------------Component "Constructor"----------------------- Sub InitializeComponent() Element.style.width = "192px" Element.style.height = "94px" Element.style.backgroundcolor = "menu" Element.style.borderStyle = "outset" Element.style.borderwidth = "thin" Set LogonTitleText = Element.document.CreateElement("<input id=""LogonTitleText"" tabindex=""-1"" style=""font-weight: bold; font-size: 8pt; Left: 3px; width: 185px; border-top-style: none; font-family: verdana; border-Right-style: none; border-Left-style: none; position: absolute; top: 3px; text-decoration: underline; border-bottom-style: none; background-color: menu;"" type=""text"" value=""Logon (ACCT05 Credentials)"" readonly=""readOnly"" />") Set UserNameText = Element.document.CreateElement("<input id=""UserNameText"" tabindex=""-1"" style=""font-size: 8pt; Left: 3px; width: 69px; border-top-style: none; font-family: verdana; border-Right-style: none; border-Left-style: none; position: absolute; top: 24px; border-bottom-style: none; background-color: menu;"" type=""text"" value=""User name:"" readonly=""readOnly"" />") Set UserNameValueText = Element.document.CreateElement("<input id=""UserNameValueText"" tabindex=""999"" style=""font-size: 8pt; Left: 73px; width: 114px; font-family: verdana; position: absolute; top: 22px"" type=""text"" />") Set PasswordText = Element.document.CreateElement("<input id=""PasswordText"" tabindex=""-1"" style=""font-size: 8pt; Left: 3px; width: 69px; border-top-style: none; font-family: verdana; border-Right-style: none; border-Left-style: none; position: absolute; top: 47px; border-bottom-style: none; background-color: menu;"" type=""text"" value=""Password:"" readonly=""readOnly"" />") Set PasswordValueText = Element.document.CreateElement("<input id=""PasswordValueText"" tabindex=""1000"" style=""font-size: 8pt; Left: 73px; width: 114px; font-family: verdana; position: absolute; top: 45px"" type=""password"" />") Set OkButton = Element.document.CreateElement("<input id=""OkButton"" tabindex=""1001"" style=""font-size: 8pt; Left: 3px; font-family: verdana; position: absolute; top: 68px; width: 60px;"" type=""button"" value=""OK"" />") Set CancelButton = Element.document.CreateElement("<input id=""CancelButton"" tabindex=""1002"" style=""font-size: 8pt; Left: 127px; font-family: verdana; position: absolute; top: 68px"" type=""button"" value=""Cancel"" />") Element.AppendChild(LogonTitleText) Element.AppendChild(UserNameText) Element.AppendChild(UserNameValueText) Element.AppendChild(PasswordText) Element.AppendChild(PasswordValueText) Element.AppendChild(OkButton) Element.AppendChild(CancelButton) PasswordValueText.AttachEvent "onkeypress", GetRef("CheckKey") UserNameValueText.AttachEvent "onkeypress", GetRef("CheckKey") OkButton.AttachEvent "onclick", GetRef("TryLogon") CancelButton.AttachEvent "onclick", GetRef("CancelLogon") HideLogon() End Sub '-----------------------Internal Event Handlers----------------------- Function ValidLogin(UserID,UserPassword) On Error Resume Next Set ValidLogin = GetObject("LDAP:").OpenDSObject("LDAP://<Domain Controller>/DC=<DC>,DC=com","<DC>\" + UserID,UserPassword,1 + 512) ValidLogin = (Err.Number = 0) End Function Sub CheckKey() If window.event.keyCode = 13 Then TryLogon() : End If : End Sub Sub TryLogon() On Error Resume Next If ValidLogin(UserNameValueText.Value,PasswordValueText.Value) Then FireSuccessfullLogon() Else FailedLogon() End If HideLogon() End Sub Sub FailedLogon() HideLogon() FireUnsuccessfullLogon() End Sub Sub CancelLogon() : HideLogon() : End Sub Function GetUserID() : GetUserID = UserNameValueText.value : End Function Sub PutUserID(InUserID) : UserNameValueText.value = InUserID : End Sub Function GetPassword() : GetPassword = PasswordValueText.value : End Function Sub PutPassword(InPassword) : PasswordValueText.value = InPassword : End Sub '---------------Exposed Methods--------------- Sub ShowLogon() Element.style.display = "" Element.setCapture() If UserID = "" or IsEmpty(UserID) or IsNull(UserID) Then UserNameValueText.value = "" PasswordValueText.value = "" UserNameValueText.Select() Else UserNameValueText.value = UserID PasswordValueText.value = "" PasswordValueText.Select() End If End Sub '----------------Internal Methods---------------- Sub HideLogon() Element.style.display = "none" Element.ReleaseCapture() End Sub '--------------------Event Firing Methods-------------------- Sub FireSuccessfullLogon() : SuccessfullLogonEventID.Fire(Element.document.CreateEventObject()) : End Sub Sub FireUnsuccessfullLogon() : UnsuccessfullEventID.Fire(Element.document.CreateEventObject()) : End Sub InitializeComponent </script> Simple but very useful in any tool that requires sometimes alternate user credentials than the currently logged on user (I.E. Adding computers to Active Directory, Mapping Network Drives using alternate AD account info,...etc) by copying over the logon.htc to the tools source directory and adding very few lines of code, at most 2 lines of html and in no time at all what ever tool i'm developing has the ability to handle AD account validation. In my eyes a major time saver and a major sanity saver. You get the idea. Well when I took the same working logon.htc file along with a test.hta file which referenced and utilize the Logon component and attempted to run it while under Vista PE the HTA crashes with errors like "TestLogon does not support .ShowLogon()" I mapped over to my development network share from Vista PE and launched one of my working examples with the Logon component added and enabled would not work in PE (would work in XP or windows 2000) I even tried to create a barebones htc with one <Public:Property /> tag and even it errors out in PE but works fine in normal windows. This is really frustrating simply due to the fact I have been working hard and pushing process changes through to management to standardize and encapsulate our more commonly reused scripting tasks so I and the other developers don't have to keep rescripting the same old stuff over and over for every tool we are tasked with developing. but I digress long and short I would like to get this working in Vista PE if that is possible I would like to find out if there is some additional settings I need to change or build into the boot.wim to get HTC's to operate correctly in VistaPE If anyone has any ideas or can point me in the direction of something more than just generic "how to deploy windows vista" FAQ’s I would greatly appreciate it. Thanks in advance for any and all help Cheers, Ryan Strope Distributed Services (Software package development/testing) Lockheed Martin Systems Integration Owego (Cyber City Computers) ryan.strope@lmco.com Quid quid latine dictum sit, altum videtur
  6. Phil, Well if you have multiple buttons you want to behave the same way here's the easiest way you can implement it with minimal code The original Button1_MouseWheel Event handler gets modified to look like the following Private Sub Button_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseWheel, Button2.MouseWheel If CType(sender, System.Windows.Forms.Button).Focused Then If Not IsNumeric(CType(sender, System.Windows.Forms.Button).Text) Then CType(sender, System.Windows.Forms.Button).Text = "0" If (e.Delta < 0) Then CType(sender, System.Windows.Forms.Button).Text = (CInt(CType(sender, System.Windows.Forms.Button).Text) - 1).ToString() Else CType(sender, System.Windows.Forms.Button).Text = (CInt(CType(sender, System.Windows.Forms.Button).Text) + 1).ToString() End If End If End Sub Here's the original one so we can do some comparisons Private Sub Button1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseWheel If Button1.Focused Then If Not IsNumeric(Button1.Text) Then Button1.Text = "0" If (e.Delta < 0) Then Button1.Text = (CInt(Button1.Text) - 1).ToString() Else Button1.Text = (CInt(Button1.Text) + 1).ToString() End If End If End Sub First of you will notice the Button1_MouseWheel has been changed to Button_MouseWheel, this is not required I find it just helps to keep someone from assuming something by glancing at the code. Next you will notice all the Button1. instances have been replaced with CType(sender,System.Windows.Forms.Button). What we've done with the last change is change the event handler from a specific control id's event handler to a generic button event handler. The sender object which you will notice in ALL event handlers is an Object. Is the control that raised the event (i.e. Button1) Since literally everything in .NET is inherited from the Object Object you can use the CType() Short for Convert Type method to Explicitly convert the sender back into its System.Windows.Forms.Button Object which means you can then access any of its methods and properties just like you would directly using Button1.Text The last item on the change list is at the end of the Handles keyword in the original event handler you had Handles Button1.MouseWheel but in the update event handler you have Handles Button1.MouseWheel, Button2.MouseWheel Essentially you now have 1 event handler attached to handle 2 buttons’ MouseWheel events. As you might have guessed you can add as many Button's after the Handles keyword as you want. So continuing with that logic our MouseEnter event handler becomes Private Sub Button_MouseEnter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.MouseEnter, Button2.MouseEnter CType(sender, System.Windows.Forms.Button).Select() End Sub And to handle when the mouse is not on the button we add Private Sub Button_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.MouseLeave, Button2.MouseLeave SomeOtherWindowFormControl.Select() End Sub The last event handler will select another element rendering the button (sender) that raised the event unselected (bear in mind that SomeOtherWindowFormControl is another Control in your form or it is a dummy control made hidden) So let's recap we changed our event handlers from what we will call explicit event handlers to be generic event handlers with multiple controls’ specific event being handles by 1 event handler. We changed the name of the event handlers from Button1_Mouse????? to Button_Mouse????? in a nut shell this is to keep you and anyone else who reads through your code from thinking that Button1_Mouse???? is a generated event handler for Button1 only (which is not the case here) Again not needed but a little house cleaning now will save your sanity when you revisit the code after you haven't looked at it for months and have forgotten the little idiosyncrasies like Button1_MouseWheel is actually tied to multiple buttons not just Button1. We added a Button_MouseLeave event handler to move focus off the current active button to another predefined control in the form as soon as the mouse cursor leaves the confines of the current active button. Hope that makes things a little easier for you feel free to ask for clarification if you need it. Please understand though my primary .NET language is C# so I cannot claim to know everything about how VB.NET handles events. Also don't just take my coding advice as the gospel truth these are just things I have learned over the years and methods I have adopted to keep me out of trouble and minimize my rework. advice is good and should always be welcomed as well as offered but in the end you need to find what works consistently for you. Hope you have a happy holiday. Cheers, Ryan Strope Distributed Services (Software package development/testing) Lockheed Martin Systems Integration Owego (Cyber City Computers) ryan.strope@lmco.com Quid quid latine dictum sit, altum videtur
  7. To All, I'm kind of excited but kind it's sort of surreal that this is my first Post of a fix to my own problem First off I would like to thank everyone who took the time to comment and help out with this especially Br4tt3 Turns out ADSI was functioning just fine in PE (after adding the required files and registry updates to the WIM) The problem as Br4tt3 alluded to was in the script itself. Unfortunately I do not know EVERYTHING about ADSI... ...Yet... So I completely missed the relevance Also apparently looking at the date of this first post it's been almost a year of leaving this on the back burner while I cooked up other tools and utilities for the corporation. So cue the Elton John Lion King theme song (just trust me it will make sense later) I would like to share with anyone who is interested briefly how I came to the stunningly obvious "WOW I'm an ID10T!!!!" epiphany I had been tasked middle of the year to develop a tool to allow our Computer Imaging Administrators to be able to quickly and efficiently create computer accounts in AD with specific security groups assigned to its ACE's for stuff like Joining the domain, rename etc. In the end I came up with a centralized HTA which allowed for traversing the active OU structure in either direction. The tool also defaulted to use cached credentials for ADSI operations but had the option to enter a domain User Name and Password to validate using the OpenDSObject() method so the tool can be run on an account that may not have the same level of permissions needed to create a computer in AD Long story short works like a charm and even after 6 months of minor OU restructuring I haven't had to modify the code once (if you can't tell I strive to develop tools that can adapt within reason to environmental changes) The biggest thing I took out of that project was how to consistently validate a domain user name and password in a script using LDAP Function ValidLogin(UserName,Password) On Error Resume Next Set ValidLogin= GetObject("LDAP:").OpenDSObject("LDAP://" & GetObject("LDAP://rootDSE").Get("defaultNamingContext"), UserName, Password, 1) ValidLogin = (Err.Number = 0) End Function Anything I develop now that requires a user name and password I use that function or a variation on it (really makes it nicer on the technicians who have to use my tools so they don't have to remember other passwords and logins) Fast Forward to about a week ago.... I was again tasked with creating a similar tool this time to allow a computer in a workgroup to both create its own account in AD and join itself to its domain. So... being the lazy developer I am I ripped out the core code for creating the computer accounts in AD from my other tool, wrapped it in a simple HTA with a login prompt using the same LDAP based validation (to allow for entering a user's credentials with enough privileges to actually create the account in AD) and an Add Computer button. I tossed it all on a test machine I had deliberately deleted from AD Ran it and........... "Invalid user name or password?"........... Retried password ........ "Invalid user name or password??"........... Tried another login....... "Enough already with the Invalid user name or password!!!!!".......... Finally had the clarity to load up Visual Studio 2005, attach to the HTA's process and debug the sucker. That's when I realized I wasn't even getting an object back from the GetObject("LDAP://RootDSE") method....... might explain why nothing is working right. Shortly thereafter I had the "You dumb a** the computer isn't even part of the domain so AD is OBLIVIOUS to its LDAPesque attempts to talk to the domain" moment A few Google searches later and I had my answer, server binding directly to a domain controller In a nutshell Set Domain = GetObject("LDAP:").OpenDSObject("LDAP://DC=MyDomain,DC=com",UserName,Password,1) becomes... Set Domain = GetObject("LDAP:").OpenDSObject("LDAP://MyDomainController/DC=MyDomain,DC=Com",MyDomain\UserName,Password,1 + 512) where the three important changes are LDAP:// -> LDAP://MyDomainController/ UserName -> MyDomain\UserName 1 -> 1 + 512 (1 is ADSI Secure Authentication, and 512 is ADSI Server Bind) Once I had updated the code to bind to the domain controller viola suddenly my tool liked my user name and passwords again and it was able to create the computer account in AD without a hitch. Fast forward again to a few hours ago. Booted up PE 2.0 to reimage my laptop (I had fried the OS testing piloted software for the corporation) symbolically beginning the end of the obligatory circle of life for me this year. (told you it would make sense later... the background music in your head should now be raising to that nice crescendo during the bridge, you know the part where you're supposed to get all emotional and "identify" with the main character as he stuggles to overcome....yeah......never mind.) As I was waiting for Ghost to backup my exiting data I finally put 2 and 2 together, Thank you high school logic chapter in math... If computer is in a WORKGROUP then it must use a server bind to a domain controller to access AD PE 2.0 loads in a WORKGROUP So...... drum roll please, If a computer is running PE 2.0 then it must use a server bind to a domain controller to access AD Seemed simple enough logic in my head, so while I waited for ghost to backup my data from the laptop I tossed open VBSEdit in PE's command prompt and mashed together a quick and dirty script to return a computer with a distinguished name I already knew of the top of my head using the domain controller server binding. A few lines of code later and a quick running of the script and all I can really say is. Yay......It works!!!!! So that's my long drawn out story. In the end I have learned 3 infallible truths out of this experience Even plastic soft touch keyboards will make your forehead bleed if you beat it against it enough If you lose enough blood it’s hard to focus on your computer screen or remember things like your name. Keyboard keys tend to stick when blood dries under them I'm hoping it will at least help someone avoid having to clean and disinfect their keyboard... or at the very least give someone a cheap laugh at my expense Cheers,
  8. Phil, I'm sorry I didn't quite understand what you were wanting to do I thought you would have already had the button under focus. If you would like to do that when the mouse hovers over the button, then this along with the other Event Handler I sent you will do the trick Private Sub Button1_MouseHover(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.MouseHover Button1.Select() End Sub Essentially all this does is whenever you hover your mouse over the button it selects the button as the active control which means the wheel Event Handler will now do its job. The .Select() method can be kind of convoluted if you're not used to working with forms controls the .Select() method is related to .Focused Property of each form element. While .Focused is a read-only Property that you can use programmatically to determine if a specific form element is the currently active element or not, .Select() is the programmatic method to make an element the currently active element (I’ll never understand why they didn't do .Focused and .Focus() ) One side not is the MouseHover event handler has a preset timeout before it fires it's pretty short but not instantaneous when you move the mouse into the button (not sure what the timeout is don't use that event as much myself), but if you find the .MouseHover is not responding quick enough you can use the .MouseEnter Event Handler Private Sub Button1_MouseEnter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.MouseEnter Button1.Select() End Sub This Event fires as soon as the mouse cursor enters the Element's physical border. Either way will accomplish what you need. Feel free to let me know if you need some more direction but if you want that kind of mouse based control look a little deeper into the .Mouse??????? Event handlers they should be very useful to you once you understand what each does. Cheers, Ryan Strope Distributed Services (Software package development/testing) Lockheed Martin Systems Integration Owego (Cyber City Computers) ryan.strope@lmco.com Quid quid latine dictum sit, altum videtur
  9. Phil, You're correct you’re missing something right in front of you. The Delta portion of the mouse event arguments only tells you the direction the mouse wheel is being turned (+) away from you (-) towards you The Mouse Wheel event fires for every preset fractional rotation of the mouse. Here is your code updated to do what you want Private Sub Button1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseWheel If Button1.Focused Then If Not IsNumeric(Button1.Text) Then Button1.Text = "0" If (e.Delta < 0) Then Button1.Text = (CInt(Button1.Text) - 1).ToString() Else Button1.Text = (CInt(Button1.Text) + 1).ToString() End If End If End Sub Couple things to note here as your script stands no matter where you are in your form the wheel will change that button from -1 to 1 and so on. adding the If Button1.Focused Then line ensures it will only perform its intended function when the button is the actively selected element. The If Not IsNumeric(Button1.Text) Then Button1.Text = "0"line is only there as a safe guard to ensure the Button has a string that can be converted into a number without raising an exception Then it's just a matter of checking if e.Delta is (-) or (+) and converting the Button's Text to its integer equivalent subtracting or adding 1 respectively and converting the value back to a string for the Button's Text Hope that helps Cheers, Ryan Strope Distributed Services (Software package development/testing) Lockheed Martin Systems Integration Owego (Cyber City Computers) ryan.strope@lmco.com Quid quid latine dictum sit, altum videtur
  10. Hello Everybody. Not entirely sure if this is the right forum for this question but it's as close as I can get right now so I’ll give it a shot. I have a script that I cannot get a specific part to work and I am lost as to what I should do. Here's the scenario I have been over the last year developing/fixing exiting and new ADSI management scripts our Imaging Department uses Add/Remove/Update/Move Computer accounts in AD My predecessor left us with several I’ll call them "legacy" scripts for lack of a better term that doesn't sound vile. This basically contained only slightly modified blindly copy and pasted Microsoft TechNet examples or scripting guy’s examples. To make a long frustrating story short I'm trying deal with updating a poorly written set of AD management scripts that are about as cohesive and adaptive as water and Cesium (and half the time they have about the same affect on our OU) One of the first scripts I rewrote was a long drawn out vbscript file with 15+ input boxes to add a computer to one of our OU's and add an account as having the permissions to join the pc to the domain, rename it etc. I created a set of HTA files to manage the process the vbscript file did effectively putting all the separate linear choices in the original vbscript file into a GUI with general predefined settings and logging. We only run the Tool on a system which is authenticated to the domain (the GUI has a login function bouncing off of ADSI's GetDSObject method to facilitate temporarily running the Tool on a system that is not currently logged in with our domain administrative account) it basically does the following: Add the PC to the selected OU Update the PC's DACL so our small Support Security Group is the only ones who can join the PC to the domain Log the results to an excel file Now there are a small sub group of PC's that either due to AD timeout or special circumstances we do not add to the domain using our tool. To facilitate that we have another Beautifully written legacy script that lets us run it on a computer that is still in a workgroup essentially add itself to the domain using WMI. the problem is doing this voids all of the security descriptor settings we need to set and our Support Security Group does not have access to join the pc to the domain, etc. To try and correct the problem I basically replicated the core function of the HTA I had described early. To facilitate joining the domain from a workgroup I updated the OpenDSObject's parameters to include an explicit server bind to our domain controller. Now the part of the HTA that adds the computer to the Domain works just as it does in the normal Tool And after the account is created I can pull the ntSecurityDescriptor, and get its DACL, I can even add all the required ACEs to the DACL But when I finally get back to objComputer.Put "ntSecurityDescriptor",objSecurityDescriptor It Errors out saying "The security ID structure is invalid" I can go out to AD and see the computer has been added so I know that's working. And I really haven't changed the coding that adds the ACE's and updates the DACL from the original tool. I'm really lost and I can't seem to find anything that's not disambiguous to Exchange server in my searches. Here's the entire code block of the HTA if anyone can find the problem I would really appreciate it (mind you the exact same core functions have not been modified with the exception of the Domain Controller Server Bind from the original HTA tool which does everything as it should when run on a PC already a member of AD) <html> <!-- The purpose of this script to allow DS bench personnel to join a PC to the acct05\domain 'Author: Ryan Strope 'Date: 12/13/07; 'Version: 1.0 --> <head> <hta:Application id="JD" Applicationname="JD" border="thin" borderstyle="raised" caption="yes" icon="" maximizebutton="No" minimizebutton="No" showintaskbar="NO" singleinstance="yes" scroll="no" sysmenu="yes" contextmenu="yes" selection="yes" version="1.0" windowstate="normal" /> </head> <body> <script language="vbscript" type="text/vbscript"> On Error Resume Next '----------------------Component Constants---------------------- Const ADMIN = 1 Const USER = 2 Const OTHER = 1 Const UNKNOWN = 2 Const DESKTOP = 3 Const LOW_PROFILE_DESKTOP = 4 Const PIZZA_BOX = 5 Const MINI_TOWER = 6 Const TOWER = 7 Const PORTABLE = 8 Const LAPTOP = 9 Const NOTEBOOK = 10 Const HANDHELD = 11 Const DOCKING_STATION = 12 Const ALL_IN_ONE = 13 Const SUB_NOTEBOOK = 14 Const SPACE_SAVING = 15 Const LUNCH_BOX = 16 Const MAIN_SYSTEM_CHASSIS = 17 Const EXPANSION_CHASSIS = 18 Const SUB_CHASSIS = 19 Const BUS_EXPANSION_CHASSIS = 20 Const PERIPHERAL_CHASSIS = 21 Const STORAGE_CHASSIS = 22 Const RACK_MOUNT_CHASSIS = 23 Const SEALED_CASE_PC = 24 'Global Functions Function PopulateACES(Trustee, AccessMask, AceFlags, AceType, Flags, ObjectType) Dim LocalACE Set LocalACE = CreateObject("AccessControlEntry") LocalACE.Trustee = Trustee LocalACE.AccessMask = AccessMask LocalACE.AceFlags = AceFlags LocalACE.AceType = AceType If Not IsEmpty(Flags) Then LocalACE.Flags = Flags If Not IsEmpty(ObjectType) Then LocalACE.ObjectType = ObjectType Set PopulateACES = LocalACE End Function Function addUser(byVal Computer, byVal AdminGroup, byVal LDAPPath) Dim objRootDSE Dim objContainer Dim objComputer Dim objSecurityDescriptor Dim objDACL Const ADS_OPTION_SECURITY_MASK = 3 Const ADS_SECURITY_INFO_DACL = &H4 Const ADS_UF_PASSWD_NOTREQD = &h0020 Const ADS_UF_WORKSTATION_TRUST_ACCOUNT = &h1000 Const ADS_ACETYPE_ACCESS_ALLOWED = &h0 Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = &h5 Const ADS_FLAG_OBJECT_TYPE_PRESENT = &h1 Const ADS_RIGHT_GENERIC_READ = &h80000000 Const ADS_RIGHT_DS_SELF = &h8 Const ADS_RIGHT_DS_WRITE_PROP = &h20 Const ADS_RIGHT_DS_CONTROL_ACCESS = &h100 Const ALLOWED_TO_AUTHENTICATE = "{68B1D179-0D15-4d4f-AB71-46152E79A7BC}" Const RECEIVE_AS = "{AB721A56-1E2f-11D0-9819-00AA0040529B}" Const SEND_AS = "{AB721A54-1E2f-11D0-9819-00AA0040529B}" Const USER_CHANGE_PASSWORD = "{AB721A53-1E2f-11D0-9819-00AA0040529b}" Const USER_FORCE_CHANGE_PASSWORD = "{00299570-246D-11D0-A768-00AA006E0529}" Const USER_ACCOUNT_RESTRICTIONS = "{4C164200-20C0-11D0-A768-00AA006E0529}" Const VALIDATED_DNS_HOST_NAME = "{72E39547-7B18-11D1-ADEF-00C04FD8D5CD}" Const VALIDATED_SPN = "{F3A64788-5306-11D1-A9C5-0000F80367C1}" Const ADS_SECURE_AUTHENTICATION = 1 Set objContainer = GetObject("LDAP:").OpenDSObject(LDAPPath,"acct05\" + UserNameHidden.value,PasswordHidden.value,1 + 512) Set objComputer = objContainer.Create("Computer", "cn=" & Computer) objComputer.Put "sAMAccountName", Computer & "$" objComputer.Put "userAccountControl", ADS_UF_PASSWD_NOTREQD Or ADS_UF_WORKSTATION_TRUST_ACCOUNT 'On Error Resume Next objComputer.SetInfo If(Err <> 0) Then addUser = "Possible Duplicate Not Created" Else Set objComputer = GetObject("LDAP:").OpenDSObject(replace(LDAPPath,"A05DC21/","A05DC21/CN=" + Computer + ",",1,-1,1),"acct05\" + UserNameHidden.value, PasswordHidden.value,1 + 512) Set objSecurityDescriptor = objComputer.Get("ntSecurityDescriptor") Set objDACL = objSecurityDescriptor.DiscretionaryAcl objDACL.AddAce PopulateACES(AdminGroup, ADS_RIGHT_GENERIC_READ, 0, ADS_ACETYPE_ACCESS_ALLOWED,Empty,Empty) ' objACE2 through objACE6: Extended Rights objDACL.AddAce PopulateACES(AdminGroup, ADS_RIGHT_DS_CONTROL_ACCESS, 0, ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, ADS_FLAG_OBJECT_TYPE_PRESENT, ALLOWED_TO_AUTHENTICATE) objDACL.AddAce PopulateACES(AdminGroup, ADS_RIGHT_DS_CONTROL_ACCESS, 0, ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, ADS_FLAG_OBJECT_TYPE_PRESENT, RECEIVE_AS) objDACL.AddAce PopulateACES(AdminGroup, ADS_RIGHT_DS_CONTROL_ACCESS, 0, ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, ADS_FLAG_OBJECT_TYPE_PRESENT, SEND_AS) objDACL.AddAce PopulateACES(AdminGroup, ADS_RIGHT_DS_CONTROL_ACCESS, 0, ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, ADS_FLAG_OBJECT_TYPE_PRESENT, USER_CHANGE_PASSWORD) objDACL.AddAce PopulateACES(AdminGroup, ADS_RIGHT_DS_CONTROL_ACCESS, 0, ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, ADS_FLAG_OBJECT_TYPE_PRESENT, USER_FORCE_CHANGE_PASSWORD) ' objACE7: Property Sets objDACL.AddAce PopulateACES(AdminGroup, ADS_RIGHT_DS_WRITE_PROP, 0, ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, ADS_FLAG_OBJECT_TYPE_PRESENT, USER_ACCOUNT_RESTRICTIONS) ' objACE8 and objACE9: Validated Rights objDACL.AddAce PopulateACES(AdminGroup, ADS_RIGHT_DS_SELF, 0, ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, ADS_FLAG_OBJECT_TYPE_PRESENT, VALIDATED_DNS_HOST_NAME) objDACL.AddAce PopulateACES(AdminGroup, ADS_RIGHT_DS_SELF, 0, ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, ADS_FLAG_OBJECT_TYPE_PRESENT, VALIDATED_SPN) objSecurityDescriptor.DiscretionaryAcl = objDACL objComputer.Put "ntSecurityDescriptor", objSecurityDescriptor msgbox err.description & "12 "& err.number & " " & err.Source err.Clear() objComputer.SetOption ADS_OPTION_SECURITY_MASK, ADS_SECURITY_INFO_DACL objComputer.SetInfo msgbox err.description & "13 "& err.number err.Clear() msgbox "Test" addUser = "Success" End If Set objRootDSE = Nothing Set objContainer = Nothing Set objComputer = Nothing Set objSecurityDescriptor = Nothing On Error GoTo 0 End Function Function ValidLogin() On Error Resume Next Set ADTestLoginObject = GetObject("LDAP:").OpenDSObject("LDAP://A05DC21/DC=ACCT05,DC=us,DC=lmco,DC=com","acct05\" + UserNameHidden.value,PasswordHidden.value,1 + 512) ValidLogin = (Err.Number = 0) End Function Function GetComputerName() : For Each BIOS In GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("Select SerialNumber from Win32_BIOS"): GetComputerName = ucase(BIOS.SerialNumber) : Next : End Function Function JoinTheDomain() If Not ValidLogin() Then Window.alert("Invalid User ID or Password." + vbcrlf + vbcrlf + "Please try again or contact your network administrator.") UserNameHidden.value = "owgpcset" PasswordHidden.value = "" PasswordHidden.select() Else if GetChassis() = "Laptop" then LDAPHidden.value = replace(LDAPHidden.value,"Workstations","Laptops",1,-1,1) AddComputers() End If End Function Function Is_System_Supported(Supported_Chassis_Types) If IsEmpty(Supported_Chassis_Types) Then Is_System_Supported = True : Exit Function For Each Chassis In GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("Select ChassisTypes from Win32_SystemEnclosure") : For Each SupportedChassis In Supported_Chassis_Types : If SupportedChassis = Chassis.ChassisTypes(0) Then Is_System_Supported = True : Exit Function : End If : Next : Next Is_System_Supported = False End Function 'Is_System_Supported(Supported_Chassis_Types) Function GetChassis() GetChassis = "Desktop" If Is_System_Supported(Array(PORTABLE,LAPTOP,NOTEBOOK,DOCKING_STATION,SUB_NOTEBOOK,PERIPHERAL_CHASSIS)) Then GetChassis = "Laptop" End Function 'Global Subs Sub AddComputers() If (addUser(GetComputerName(),UserGroupHidden.value,LDAPHidden.value) = "Success") Then If window.confirm("This " + GetChassis() + " has been successfully joined to the " + GetChassis() + " domain, Would you like to reboot now?") Then Reboot() window.close() Else window.alert("This " + GetChassis() + " could not join the " + GetChassis() + " domain. A duplicate name already exits" + vbCrLf + "Please attempt to join the domain manually, or contact your system administrator...") window.close() End If End Sub 'InstallSelectedComputerlications(ComputersNames, ComputersPaths) Sub Reboot : For Each OS in GetObject("winmgmts:{(Shutdown)}").ExecQuery("Select * from Win32_OperatingSystem") : OS.Reboot : Next : End Sub 'Event Handlers Sub Window_onload() window.moveTo 300,100 window.resizeTo 300,120 JoinButton.value = "Join this " + GetChassis() + " to the ACCT05 domain" PasswordHidden.select() document.title="Join " + UCase(GetComputerName()) + " to the ACCT05 Domain" End Sub 'Window_onload() Sub CheckKey() If window.event.keyCode = 13 Then JoinTheDomain() : End If : End Sub </script> <textarea id="Title" style="font-weight: bold; font-size: 10pt; left: 5px; overflow: hidden; width: 280px; border-top-style: none; font-family: verdana; border-right-style: none; border-left-style: none; position: absolute; top: 2px; height: 18px; border-bottom-style: none">Enter your ACCT05 Logon.</textarea> <input id="PasswordHidden" onkeypress="CheckKey()" type="password" value="" style="font-size: 10pt; left: 83px; border-top-style: none; border-bottom: blue thin solid; font-family: verdana; border-right-style: none; border-left-style: none; position: absolute; top: 40px; width: 201px;" /> <input id="UserNameHidden" type="Text" value="owgpcset" style="border-right: blue thin; border-top: blue thin; font-size: 10pt; left: 83px; border-left: blue thin; border-bottom: blue thin solid; font-family: verdana; position: absolute; top: 19px; width: 201px;" /> <input id="UserIDText" type="text" value="User ID:" style="font-size: 10pt; left: 5px; border-top-style: none; font-family: verdana; border-right-style: none; border-left-style: none; position: absolute; top: 20px; border-bottom-style: none; vertical-align: middle; text-align: right; width: 72px;" /> <input id="PasswordText" type="text" value="Password:" style="font-size: 10pt; left: 5px; border-top-style: none; font-family: verdana; border-right-style: none; border-left-style: none; position: absolute; top: 41px; border-bottom-style: none; vertical-align: middle; text-align: right; width: 72px;" /> <input id="LDAPHidden" type="hidden" value="LDAP://A05DC21/OU=Workstations,OU=Production,OU=Owego,OU=EPI,DC=ACCT05,DC=us,DC=lmco,DC=com" style="left: 13px; position: absolute; top: 113px" /> <input id="UserGroupHidden" type="hidden" value="owg.irm.Desktop.Admin" style="left: 175px; position: absolute; top: 113px" /> <input type="button" value="Join Domain" name="JoinButton" onClick="JoinTheDomain()" style="font-size: 10pt; left: 5px; font-family: verdana; position: absolute; top: 63px; width: 280px;" /> </body> </html> Thanks for the help and future input Cheers, Ryan Strope Distributed Services (Software package development/testing) Lockheed Martin Systems Integration Owego (Cyber City Computers) ryan.strope@lmco.com Quid quid latine dictum sit, altum videtur
  11. Wondering if anyone has come across a solution to the following problem. I need to be able to run a silent uninstall of Visio 2007 (Both Professional and Standard) the problem is i can't get rid of a couple of dialog boxes despite having all the required MS options set The Installation is done through a generated MSP file from the OCT for both version that works beautifully and runs silently as needed however the uninstall i'm doing using the setup.exe /uninstall VisPro /config .\uninstall\config.xml where config.xml is: <Configuration Product="VisPro"> <!-- <Display Level="None" CompletionNotice="no" SuppressModal="yes" NoCancel="yes" AcceptEula="yes" /> --> <!-- <Logging Type="standard" Path="%temp%" Template="Microsoft Office Visio Professional Setup(*).txt" /> --> <!-- <Setting Id="SETUP_REBOOT" Value="NEVER" /> --> <!-- <Command Path="msiexec.exe" Args="/i \\server\share\my.msi" QuietArg="/q" ChainPosition="after" Execute="install" /> --> </Configuration> from everything MS says in the setup and configuration instructions on the Visio Web site that should give me a nice clean uninstall with no dialog boxes... yet i still get: "Are you sure you want to remove Microsoft Office Visio Professional 2007 from this machine?" Setup dialog box AND The "Microsoft Office Visio Professional 2007 has been successfully uninstalled" completion dialog box AND The "In order to complete setup, a system reboot is necessary. Would you like to reboot now?" dialog box With the setup i can use the /adminfile and the msp with all the same settings from the OCT and it runs perfectly silent but MS has it so you can only use the MSP on an initial install you can't use an MSP to uninstall for instance you are stuck using the /uninstall and /config setup options which don't seem to be accomplishing anything they should be doing If anyone has any ideas I'd appreciate it Cheers, Ryan Strope Distributed Services (Software package development/testing) Lockheed Martin Systems Integration Owego (Cyber City Computers) ryan.strope@lmco.com Quid quid latine dictum sit, altum videtur
  12. May be a little late seeing as we're into August but if you want a solid way to reboot PE from an HTA This is what I use any time I need to reboot (Works in PE 1.5, 1.6, 2.0 as well as XP, 2000 ... haven't tried it in vista only because my company is not deploying vista as a production image yet) Function RestartComputer() For Each OS in GetObject("winmgmts:{impersonationLevel=impersonate,(Shutdown)}!\\.\root\cimv2").ExecQuery("Select * from Win32_OperatingSystem") OS.Reboot() Next End Function As long as you have WMI loaded it will work (NOTE: depending on the speed of the Computer it may take WMI a few seconds to process the restart request be patient it will happen) I like to keep a small collection of functions like the one above that i know will operate the same no matter the platform I'm running them on (thankfully we currently only support 2000 and XP) the less re-work i have to do the more time I have to focus on the fun stuff rewriting decade old legacy support tools. Hope that helps. Cheers, Ryan Strope Distributed Services (Software package development/testing) Lockheed Martin Systems Integration Owego (Cyber City Computers) ryan.strope@lmco.com Quid quid latine dictum sit, altum videtur
  13. Thanks for the info I've signed up for his forum just have to wait for ye ole authorization. Cheers, Ryan Strope Distributed Services (Software package development/testing) Lockheed Martin Systems Integration Owego (Cyber City Computers) ryan.strope@lmco.com Quid quid latine dictum sit, altum videtur
  14. And that's the answer i have been getting everywhere i look. you're running it from the CD but your unzipping it to the hard drive before you launch the setup this particular DVD has to be able to launch the setup itself from the DVD the requirements i have are nothing goes down on the local hard drive except the installed software and any modified configuration files needed (ini, xml etc) When i get into the office on monday i will be attempting to set up a log file to see if i can narrow down what's flagging the 1602 Cheers, Ryan Strope Distributed Services (Software package development/testing) Lockheed Martin Systems Integration Owego (Cyber City Computers) ryan.strope@lmco.com Quid quid latine dictum sit, altum videtur
  15. I wouldn't be waisting my time on 1.1 if they didn't need it a lot of the postal sorting equipment software is dependent on .NET 1.1 as well as most of the DOD support software they develop. While i might agree 2.0 and 3.0 are much nicer and much better to use unfortunately every piece of software no matter how big or small deployed to the corporation has to go through a security and vulnerability review and then it was to go through the same type of review on the site level. To give you and idea how much of a pain in the a** that is we only JUST deployed the 2.0 framework to the corporation last week. so you can imagine how long it will take to get the 3.0 framework out Cheers, Ryan Strope Distributed Services (Software package development/testing) Lockheed Martin Systems Integration Owego (Cyber City Computers) ryan.strope@lmco.com Quid quid latine dictum sit, altum videtur