I'm writing a script to automate as much as possible of our 'preparation for deployment' process, mostly so we can impose standards and stop packagers using ridiculous names for GPOs! So far, the script creates the group, sets up the GPO, links the GPO to the relevant OU, removes 'Authenticated Users' from the permission list and adds the group created in the first step. Now, I need to add the MSI to the GPO. Does anyone have any pointers to documentation about this? I've looked at the GPMgmt.GPM object docs on MSDN but that doesn't seem to have anything which looks like it might do the job. Can it even be done in script?
0 Comments   [ + ] Show Comments

Comments

Please log in to comment

Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.

Answers

0
ORIGINAL: VBScab

I'm writing a script to automate as much as possible of our 'preparation for deployment' process, mostly so we can impose standards and stop packagers using ridiculous names for GPOs! So far, the script creates the group, sets up the GPO, links the GPO to the relevant OU, removes 'Authenticated Users' from the permission list and adds the group created in the first step. Now, I need to add the MSI to the GPO. Does anyone have any pointers to documentation about this? I've looked at the GPMgmt.GPM object docs on MSDN but that doesn't seem to have anything which looks like it might do the job. Can it even be done in script?



VB,

I'd look at ADSI scriptomatic. http://www.microsoft.com/technet/scriptcenter/tools/admatic.mspx

It should be able to give you some tools to do this. As for packagers using ridiculous names for GPOs, I'm surprised packagers have a role in creating them. Rarely do packagers have the knowledge and expertise (or the time!) to mess around like that. In a medium to large enterprise, AD is a full time job in itself.
Answered 09/12/2007 by: aogilmor
Ninth Degree Black Belt

Please log in to comment
0
Nah, no good. BTDT. Scriptomatic just provides you with a shell, to which you are expected to add the properties, methods, etc that you want to use. It's precisely the latter that I'm missing.

Thanks anyway :)
Answered 09/12/2007 by: VBScab
Red Belt

Please log in to comment
1
Hi Ian,
do you know this blog?
http://geekswithblogs.net/derekf/Default.aspx
and this one:
http://diaryproducts.net/about/operating_systems/windows/move_software_package_to_another_gpo
Some intersting info for GPO installers...
Regards, Nick
Answered 09/13/2007 by: nheim
Tenth Degree Black Belt

Please log in to comment
0
Thanks, Kim. Some tantalising clues there... It seems like I must pass the GP container as a search parameter to the GPM SearchGPO method which returns a list of GPOs that match. Then I can loop through the properties. Problem is (as far as I can tell on what I've read so far) I need to find the GPO's GUID and pass *that*.

I shan't give up. As soon as I have something, I'll share it here.
Answered 09/14/2007 by: VBScab
Red Belt

Please log in to comment
0
Ian,

Your thanks should go to Nick, shouldn't it [;)]

Nick,

Thanks for those great links!
And will certainly rate your post for that.
Cheers!
Answered 09/14/2007 by: AngelD
Red Belt

Please log in to comment
0
D'oh! Sorry Kim and Nick. [note to self: PAY ATTENTION!]
Answered 09/14/2007 by: VBScab
Red Belt

Please log in to comment
0
Thanks for the flowers folks,
Ian, please keep us posted on your findings on this interesting stuff.
Could use a few automated task myself on GPO management.
Regards, Nick
Answered 09/14/2007 by: nheim
Tenth Degree Black Belt

Please log in to comment
0
Gah! I'm *THIS* close...

I've lashed up a call to the Installer API function msiAdvertiseProduct which is supposed to create the AAS, using the venerable DynaWrap ActiveX control DLL. Problem is, it returns '2' instead of '0'. That presumably translates to 'File Not Found' but, why and how? The two file names passed in to the function are the MSI name (in UNC form) and the AAS name. Now, the MSI exists but *obviously* the AAS doesn't because that's what the function's meant to be creating!

I've used a GUID-generation tool to create the name of the AAS file - minus the left and right braces {} - and pass the whole thing, as in:

\\[domain]\SysVol\[domain]\Policies\[package GUID\User\Applications\[script GUID].AAS

Does *anyone* know what's wrong with that?
Answered 10/16/2007 by: VBScab
Red Belt

Please log in to comment
0
OK, I think the error returned (2) detailed above is a red herring. Here's the deal. [/align] I'm using the DynaWrap DLL to access the MsiAdvertiseProductA API. I've used this DLL successfully for years so I'm confident in its abilities, stability, etc. My code looks like this (much simplified):[/align] [/align] [/align] [font="courier new"]Set objDLLWrapper = WScript.CreateObject("DynamicWrapper")[/align] [font="courier new"] [/align] [font="courier new"]blnResult = objDLLWrapper.Register("MSI.DLL", "MsiAdvertiseProductA", "i=ssst", "f=s", "r=l")
'// where[/align] [font="courier new"]'// i defines the number and data type of the function's parameters
'// f defines the type of call, either _stdcall (use 's' - Microsoft C++) or _cdecl (use 'c' - Borland C++)
'// r defines the return data type.
'//
'// Data types are:
'// {'a', sizeof(IDispatch*), VT_DISPATCH}, // a IDispatch*
'// {'c', sizeof(unsigned char), VT_I4}, // c signed char
'// {'d', sizeof(double), VT_R8}, // d 8 byte real
'// {'f', sizeof(float), VT_R4}, // f 4 byte real
'// {'k', sizeof(IUnknown*), VT_UNKNOWN}, // k IUnknown*
'// {'h', sizeof(long), VT_I4}, // h HANDLE
'// {'l', sizeof(long), VT_I4}, // l long
'// {'p', sizeof(void*), VT_PTR}, // p pointer
'// {'s', sizeof(BSTR), VT_LPSTR}, // s string
'// {'t', sizeof(short), VT_I2}, // t short
'// {'u', sizeof(UINT), VT_UINT}, // u unsigned int
'// {'w', sizeof(BSTR), VT_LPWSTR}, // w wide string
[/align] [font="courier new"]lngReturn = objDLLWrapper.MsiAdvertiseProductA(strMSIFile, strAASFile, strMSTFile, intLanguage)
[/align] [/align] I've made sure that my strings (strMSIFile, strAASFile, strMSTFile) are explicitly defined as strings (using CStr) and my integer, intLanguage, is defined as an integer which, according to what I can find, is the nearest equivalent to LANGID.[/align] [/align] The reason that I suppose it's a data type issue is that if I remove the string coercion from strMSIFile, strAASFile and strMSTFile, I get the value '2' returned in lngReturn. Put it back and I get '123'. I've tried adding null - Chr(0) - and vbNull to the end of the strings and using 'w' type for the string data type but I get the same results.[/align] [/align] So, given the data type choices I have above, which should I be using for each function's parameters? I believe it's the integer which is the troublesome one: I've tried 'l', 't' and 'u'. In each case, I get '123' in lngReturn.[/align] [/align]Intriguingly (or annoyingly, depending on how many times I've re-run the damn thing), I can transplant my code more or less intact into a VB.Net project and it works. The principle difference is that I've used Int16 as the data type for LANGID. Now, obviously I could create a DLL from VB.Net and simply use that. However, I want to have a solution which I could leave with my client which allows them the flexibility of VB Script, not tie them into maintaining DLLs with Visual Studio.[/align]
[/align]
Answered 10/17/2007 by: VBScab
Red Belt

Please log in to comment
0
Hi Ian,
did you play around with different LangID's. Maybe, you see a scheme on the returned value and can figure out the needed conversion/typecast.
Regards, Nick
Answered 10/18/2007 by: nheim
Tenth Degree Black Belt

Please log in to comment
0
You *know* I played around...that's what I do. I'm almost resigned to using a custom DLL now, just to get the script out in the field but I will persist. I have a post on gptalk@freelists.org, where "The GPO Guy" hangs out. He wrote the GPExpert Scripting Toolkit which has a one-step method for creating the AAS (so, incidentally, does WI 4.0...) and did his best to discourage me but I WILL NOT BE BEATEN! :) Hopefully he'll respond with something, a hint at least.
Answered 10/18/2007 by: VBScab
Red Belt

Please log in to comment
0
Latest state of play:
I had to create a DLL (in VB6, if anyone cares) to provide a script-friendly interface to MSI.DLL, as DynaWrap, the ActiveX interface I *was* using, proved unreliable and returned some bizarre error codes. I created interfaces to all of MSI.DLL's exported functions, although I only needed one, MsiAdvertsieProductA. That's because most of the rest are already exposed by the Installer object. As and when I come across ones I need, I'll update my DLL.

The script now runs to completion with no errors, creating the group, GPO, GPO links, the AAS script file...everything looks good. EXCEPT...when I try to examine the package in GPEdit, the 'Software Installation' leaf doesn't appear. I figure if that's not there, there's no chance the package will get deployed.

[font="times new roman"]In the documentation for the function MSIAdvertiseProduct (http://msdn2.microsoft.com/en-us/library/aa370056.aspx), the parameter szScriptfilePath is clearly meant to be a string:

szScriptfilePath[/align] [font="times new roman"]The full path to script file that will be created with the advertise information. To advertise the product locally to the computer, set ADVERTISEFLAGS_MACHINEASSIGN or ADVERTISEFLAGS_USERASSIGN. [/align] [font="times new roman"]but then it talks about the flag: [font="times new roman"]Flag [font="times new roman"]Meaning [font="times new roman"]ADVERTISEFLAGS_MACHINEASSIGN
0 [font="times new roman"]Set to advertise a per-machine installation of the product available to all users. [font="times new roman"]ADVERTISEFLAGS_USERASSIGN
1 [font="times new roman"]Set to advertise a per-user installation of the product available to a particular user.[/align] [font="times new roman"]How can I set this flag? There's nowhere in the function for it! Is there a companion function I need to use first?[font="times new roman"]
[font="times new roman"]Ian
[/align][font="times new roman"]
Answered 11/22/2007 by: VBScab
Red Belt

Please log in to comment
0
An update, of sorts...

I've worked out how to use ADVERTISEFLAGS_MACHINEASSIGN and ADVERTISEFLAGS_USERASSIGN.

One passes EITHER the path to where the .AAS advertising script is to be stored OR one of the 2 flags. The first creates the .AAS and the second advertises the product to the local computer. I blame MS's opaque documentation...
Answered 04/10/2008 by: VBScab
Red Belt

Please log in to comment
0
OK, the script is done and it works, flawlessly so far. I've had to retain the custom DLL as it provides the only method I have of creating the advertising scripts, until such time as WI 4.0 becomes mainstream.

Given the work I've put into this, with next to no help from people in a position to do so (not you good folks, obviously), I will not be giving it away, which was my original intention. I just need to figure a way to protect my code and then I'll unleash it onto an unsuspecting world.
Answered 04/15/2008 by: VBScab
Red Belt

Please log in to comment
Answer this question or Comment on this question for clarity