|
|
|||||||
A while back a thread was posted that revealed a reghack for mapping drives with a GPO Script and UAC on, was not supported by Microsoft. http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Main=26719&Number=197754 The reghack required changing EnableLinkedConnections - http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Main=26424&Number=195765 Since these threads I've been wanting to revisit this. I remembered another post that discussed running your mapped drives via a vbscript called launchapp.wsf. http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Board=1&Number=192303 After looking over the script, I decided I would try to convert it for kix purposes. I had to add the ablility to accept arguments and a little error testing. It appears to run for me on my computer, but none of my clients use a GPO Script. I was wondering if someone with a GPO Script could test it and post back their results. The point of the the function is to map drives and printers in the context of the user with the UAC on (Vista, Win7) while running in a GPO script. Just create a simple mapdrives.kix file to go along with this. |
||||||||
|
|
|||||||
Got to be kidding me... no one uses a GPO script? |
||||||||
|
|
|||||||
Allen, What about using it to do something like this? Instead of: Code: if instr(@producttype,"Vista") or instr(@producttype,"Windows 7") $RC=RunAsInteractiveUser(@scriptdir + "\kix32.exe", @scriptdir + "\mapdrives.kix") ? @serror endif Code: if instr(@producttype,"Vista") or instr(@producttype,"Windows 7") $RC=RunAsInteractiveUser(shell '%COMSPEC% /C xcopy "\\$ipserver\netlogon\*.bmp" "c:\network" /d /r /y') ? @serror endif BTW, it seems to work for the original purpose. Thanks! |
||||||||
|
|
|||||||
Allen, Would it be possible to run this as another user (one with Admin Rights) if the Interactive User doesn't have Admin Rights? |
||||||||
|
|
|||||||
I would say yes... When I was working on this, I got the impression that you could pretty much set up any scheduled task with any user. However, that is not the point of THIS particular UDF. If you can make it work, post your code and maybe we can work on the UDFs to make it a new UDF that takes both a user and program. |
||||||||
|
|
|||||||
Allen, Fails to run if on a laptop and not plugged in...is there a way to modify this so the power options under the Conditions tab is disabled or not check? |
||||||||
|
|
|||||||
Interesting... that would have never crossed my mind as something to look out for... the bad news is, I'm not seeing anything obvious to fix it... here is msdn's page on this... http://msdn.microsoft.com/en-us/library/aa383607%28VS.85%29.aspx |
||||||||
|
|
|||||||
Found it!... heading out for dinner though... will see what I can come up with afterwards... http://msdn.microsoft.com/en-us/library/aa383480%28v=VS.85%29.aspx DisallowStartIfOnBatteries StopIfGoingOnBatteries |
||||||||
|
|
|||||||
You want to talk about a needle in a hay stack... I found, count them, ONE page in my google searches with an example of how to use the SETTINGS, and it was in Chinese. Nothing on MSDN explaining how to use it. The good news is, the top most post contains the updated function. See if it works any better. |
||||||||
|
|
|||||||
Originally Posted By: Allen and it was in Chinese * "wassamatta" is North-Jerseyan/Brooklyneese for "What is the matter", since we're talking about foreign languages. G- |
||||||||
|
|
|||||||
Allen, It is good to see your Chinese is still good enough to update your code...yes, it is working now. Thanks! |
||||||||
|
|
|||||||
Curious, do you use a GPO script with this or something else? |
||||||||
|
|
|||||||
Both... I have a script which updates the GPO and a local folder on the user's computer when they log in. Alot of times they are remote and so they need their drives via VPN connection. |
||||||||
|
|
|||||||
Allen, I have modified your code [adding the important Working Directory setting]: Code: Function RunAsInteractiveUser($FQFN, optional $ARGUMENTS, optional $WORKDIR, optional $TASKNAME, optional $DONOTDELETE) Dim $SERVICE, $ROOTFOLDER, $TASKDEFINITION, $TRIGGERS, $TRIGGER, $ACTION, $SETTINGS Dim $TriggerTypeRegistration, $ActionTypeExecutable, $FlagTaskCreate, $LogonTypeInteractive ? "TASK EXECUTE: " + $FQFN ? ? "TASK ARGUMENTS: " + $ARGUMENTS ? ? "TASK WORKING DIRECTORY: " + $WORKDIR ? ? "TASK NAME: " + $TASKNAME ? ? "TASK DELETE: " + $DONOTDELETE ? ? "TASK USERNAME: " + $UPPERUSERNAME ? ;$NUL = PAUSE(15) If $TASKNAME = "" $TASKNAME = "Run As Interactive User - " + @ticks EndIf $TriggerTypeRegistration = 7 $ActionTypeExecutable = 0 $FlagTaskCreate = 2 $LogonTypeInteractive = 3 If Exist($FQFN) $SERVICE = CreateObject("Schedule.Service") $SERVICE.Connect() $ROOTFOLDER = $SERVICE.GetFolder("\") $ROOTFOLDER.DeleteTask($TASKNAME, 0) $TASKDEFINITION = $SERVICE.NewTask(0) $TRIGGERS = $TASKDEFINITION.Triggers $TRIGGER = $TRIGGERS.Create($TriggerTypeRegistration) $SETTINGS = $TASKDEFINITION.Settings $SETTINGS.DisallowStartIfOnBatteries = NOT 1 $SETTINGS.StopIfGoingOnBatteries = NOT 1 $ACTION = $TASKDEFINITION.Actions.Create($ActionTypeExecutable) $ACTION.Path = $FQFN If Exist($ARGUMENTS) $Action.Arguments = '"' + $ARGUMENTS + '"' Else Exit 2 EndIf If Exist($WORKDIR) $Action.WorkingDirectory = $WORKDIR Else Exit 2 EndIf $RC = $ROOTFOLDER.RegisterTaskDefinition($TASKNAME, $TASKDEFINITION, $FlagTaskCreate,,, $LogonTypeInteractive) If NOT $DONOTDELETE Sleep 1 $ROOTFOLDER.DeleteTask($TASKNAME, 0) EndIf Else Exit 2 EndIf EndFunction |
||||||||
|
|
|||||||
Thanks for the suggestion. I'll update the top post when I get a few spare minutes. |
||||||||
|
|
|||||||
Top post updated to reflect KIXKicks suggestion. |
||||||||
|
|
|||||||
I've just implemented this in order to get away from the aforementioned registry hack - it works great. THANKS!! One minor comment, the $workdir parameter is marked optional but if you omit it (as in the example) the function will fail ("exit 2"). |
||||||||
|
|
|||||||
Thanks for letting me know you are using it. The working directory setting was added after I initially wrote this, and I see what you mean. I'll see what I can do to fix it. |
||||||||
|
|
|||||||
Would you mind trying this and see if it takes care of the problem with workdir? Code: Function RunAsInteractiveUser($KixPath, optional $kixscript, optional $workdir, optional $taskname, optional $donotdelete) Dim $service, $rootfolder, $taskdefinition, $triggers,$trigger,$action, $settings Dim $TriggerTypeRegistration, $ActionTypeExectuable,$flagtaskcreate,$logontypeinteractive if $taskname="" $taskname = "Run As Interactive User - " + @ticks endif $TriggerTypeRegistration = 7 $ActionTypeExecutable = 0 $FlagTaskCreate = 2 $LogonTypeInteractive = 3 if exist($KixPath) $service=CreateObject("Schedule.Service") $service.Connect() $rootFolder=$service.GetFolder("\") $rootFolder.DeleteTask($taskname, 0) $taskDefinition = $service.NewTask(0) $triggers = $taskDefinition.Triggers $trigger = $triggers.Create($TriggerTypeRegistration) $settings=$taskDefinition.Settings $settings.DisallowStartIfOnBatteries = not 1 $settings.StopIfGoingOnBatteries = not 1 $Action = $taskDefinition.Actions.Create($ActionTypeExecutable) $Action.Path = $KixPath if $kixscript if $exist($kixscript) $Action.Arguments = '"' + $kixscript + '"' else exit 2 endif endif if $workdir if exist($workdir) $action.WorkingDirectory = '"' + $workdir + '"' else exit 2 endif endif $rc=$rootFolder.RegisterTaskDefinition($taskname, $taskDefinition, $FlagTaskCreate,,, $LogonTypeInteractive) if not $donotdelete sleep 1 $rootFolder.DeleteTask($taskname, 0) endif else exit 2 endif endfunction |
||||||||
|
|
|||||||
Oi Allen, I was given the task to create my first logon script in the current millennium Your function works a treat, albeit Cuthbert from 3 posts above is right: You have to provide a $workdir parameter for this to work So, this one should be REQUIRED Care to post this in the udf lib? Greetz |
||||||||
|
|
|||||||
See the UDF post right above yours... it was an attempt to fix that problem. Is it still not working right? |
||||||||
|
|
|||||||
I think I was missing the point yours and the prior poster's comment of the WORKDIR Being REQUIRED. Anyway, would you clarify on this, and also provide an example of how you are using the RunAsInteractiveUser() UDF? Thanks. |
||||||||
|
|
|||||||
sure thing ... [disclaimer: nothing verified properly yet, just started to use it yesterday (locally) and today is a public holiday around here] at this very moment I call it as follows: Code: $ = RunAsInteractiveUser(@scriptdir + "\wkix32.exe", @scriptdir + "\logon.kix", @scriptdir) while the gpo will call only wkix32.exe (having the above line and the udf in 'kixtart.kix') Allthough this looks not natural the udf should be this: Code: Function RunAsInteractiveUser($KixPath, $workdir, optional $kixscript, optional $taskname, optional $donotdelete) btw.: nice effort of yours, especially the chinese transscript .. Came just in time for me |
||||||||
|
|
|||||||
Okay... so... This is the current code... and based on yours (and others) tests, $workdir must be specified. When I was testing this originally, I did not run into this, however I was only testing locally and not actually in a GPO script. Code: if $workdir if exist($workdir) $action.WorkingDirectory = '"' + $workdir + '"' else exit 2 endif endif Idea 1 Change $kixscript to required, and use path of of script as workdir by default... ie Function RunAsInteractiveUser($KixPath, $kixscript, optional $workdir optional $taskname, optional $donotdelete) Code: if $workdir="" $workdir=left($kixscript,instrrev($kixscript,"\")) endif if exist($workdir) $action.WorkingDirectory = '"' + $workdir + '"' else exit 2 endif Idea 2 By default just set the workdir to the scriptdir Code: if $workdir="" $workdir=@scriptdir endif if exist($workdir) $action.WorkingDirectory = '"' + $workdir + '"' else exit 2 endif Comments, Suggestions? |
||||||||
|
|
|||||||
Jochen, I was hoping for your comments on the suggestions above. What do you think? |
||||||||
|
|
|||||||
Hey Allen, not yet tested as GPO script .. Maybe tomorrow when the AD guy has time Ok, on your ideas. I'd prefer #2 with a twist: Let $workdir be optional as well as $kixscript but set $workdir to @scriptdir if not given. |
||||||||
|
|
|||||||
That's exactly what I was thinking on #2. Okay... So my only other concern was the fact that when I originally wrote/tested this, it worked, completely without the workdir setting. It sounds as though you are testing the same way i did, locally, not in a gpo script.... so I wonder what changed? |
||||||||
|
|
|||||||
apart from the OS? can't really tell, except that I did try on Windows 6.1 Build 7601 SP1 which translates to Win 7 Enterprise (x64) |
||||||||
|
|
|||||||
Okay... well here is the updated version, if you would be so kind to test it Code: Function RunAsInteractiveUser($KixPath, optional $kixscript, optional $workdir, optional $taskname, optional $donotdelete) Dim $service, $rootfolder, $taskdefinition, $triggers,$trigger,$action, $settings Dim $TriggerTypeRegistration, $ActionTypeExectuable,$flagtaskcreate,$logontypeinteractive if $taskname="" $taskname = "Run As Interactive User - " + @ticks endif $TriggerTypeRegistration = 7 $ActionTypeExecutable = 0 $FlagTaskCreate = 2 $LogonTypeInteractive = 3 if exist($KixPath) $service=CreateObject("Schedule.Service") $service.Connect() $rootFolder=$service.GetFolder("\") $rootFolder.DeleteTask($taskname, 0) $taskDefinition = $service.NewTask(0) $triggers = $taskDefinition.Triggers $trigger = $triggers.Create($TriggerTypeRegistration) $settings=$taskDefinition.Settings $settings.DisallowStartIfOnBatteries = not 1 $settings.StopIfGoingOnBatteries = not 1 $Action = $taskDefinition.Actions.Create($ActionTypeExecutable) $Action.Path = $KixPath if $kixscript if $exist($kixscript) $Action.Arguments = '"' + $kixscript + '"' else exit 2 endif endif if $workdir="" $workdir=@scriptdir endif if exist($workdir) $action.WorkingDirectory = '"' + $workdir + '"' else exit 2 endif $rc=$rootFolder.RegisterTaskDefinition($taskname, $taskDefinition, $FlagTaskCreate,,, $LogonTypeInteractive) if not $donotdelete sleep 1 $rootFolder.DeleteTask($taskname, 0) endif else exit 2 endif endfunction |
||||||||
|
|
|||||||
Odd! Code: $ = RunAsInteractiveUser(@scriptdir + "\wkix32.exe", @scriptdir + "\logon.kix") @serror get $ results in file not found error [exit 2] due to $kixscript |
||||||||
|
|
|||||||
whoops, @Allen, typo: line 25: Code: if $exist($kixscript) |
||||||||
|
|
|||||||
Lol.... ahhhhh so MAYBE when this typo was made the WORKDIR requirement was introduced.... hmmm |
||||||||
|
|
|||||||
BTW... nice catch and sorry for the drama of figuring it out. |
||||||||
|
|
|||||||
still doesnt work though |
||||||||
|
|
|||||||
Ok, partly my fault. Incorporated probably illegal characters in the taskname with @date and @time macros still after reverting to original I get Error 2147942667 in the scheduler event log when trying to start the task. |
||||||||
|
|
|||||||
This error translates to 267 "Invalid Directory" and happens when the working directory is handed to registration while being enclosed in quotes .. so the obvious change is line 35 to be: Code: $Action.WorkingDirectory = $workdir |
||||||||
|
|
|||||||
and a bit deeper down the rabbit hole: Working Directory is actually truly optional for scheduled tasks. So no need to force it by default.. could successfully schedule one with lines 31-38 commented, m( |
||||||||
|
|
|||||||
Recommendation: change lines 31 - 38 to: Code: if exist($workdir) $Action.WorkingDirectory = $workdir endif sorry for the 'workingdir-being-required-suspicion' confusion |
||||||||
|
|
|||||||
You still would probably want to exit if the workdir doesnt exists, I would think... which would produce the same code produced in the post on 2/16/14... WhatchuThink? Edit... Opps... added your suggestion of the $workdir without quotes Code: Function RunAsInteractiveUser($KixPath, optional $kixscript, optional $workdir, optional $taskname, optional $donotdelete) Dim $service, $rootfolder, $taskdefinition, $triggers,$trigger,$action, $settings Dim $TriggerTypeRegistration, $ActionTypeExectuable,$flagtaskcreate,$logontypeinteractive if $taskname="" $taskname = "Run As Interactive User - " + @ticks endif $TriggerTypeRegistration = 7 $ActionTypeExecutable = 0 $FlagTaskCreate = 2 $LogonTypeInteractive = 3 if exist($KixPath) $service=CreateObject("Schedule.Service") $service.Connect() $rootFolder=$service.GetFolder("\") $rootFolder.DeleteTask($taskname, 0) $taskDefinition = $service.NewTask(0) $triggers = $taskDefinition.Triggers $trigger = $triggers.Create($TriggerTypeRegistration) $settings=$taskDefinition.Settings $settings.DisallowStartIfOnBatteries = not 1 $settings.StopIfGoingOnBatteries = not 1 $Action = $taskDefinition.Actions.Create($ActionTypeExecutable) $Action.Path = $KixPath if $kixscript if exist($kixscript) $Action.Arguments = '"' + $kixscript + '"' else exit 2 endif endif if $workdir if exist($workdir) $action.WorkingDirectory = $workdir else exit 2 endif endif $rc=$rootFolder.RegisterTaskDefinition($taskname, $taskDefinition, $FlagTaskCreate,,, $LogonTypeInteractive) if not $donotdelete sleep 1 $rootFolder.DeleteTask($taskname, 0) endif else exit 2 endif endfunction |
||||||||
|
|
|||||||
I'm cool with it. |
||||||||
|
|
|||||||
Ha... was fixing it as you were replying |
||||||||
|
|
|||||||
|
||||||||
|
|
|||||||
Ok, good work there Allan, thanx a bunch. I'll let you know our results running from a GPO.. |
||||||||
|
|
|||||||
That code just above reintroduced that $exist bug... fixed the post. |
||||||||
|
|
|||||||
just wondering, maybe exploring later on: Would this work also remotely? Ah the possibilities. |
||||||||
|
|
|||||||
I would say YES... http://msdn.microsoft.com/en-us/library/windows/desktop/aa383451%28v=vs.85%29.aspx |
||||||||
|
|
|||||||
That was fast |
||||||||
|
|
|||||||
J, you think this thing is ready for posting to the UDFs? |
||||||||
|
|
|||||||
oi Allen, as things usually work, my priorities have changed. Don't give up, I'll let you know |
||||||||
|
|
|||||||
Hi Allen, I can confirm that the udf works as gpo script in a 2k8 R2 domain in We tested it to be run asynchronously but not yet synchroneously (as we don't have to as of now). And it works as advertised On a sidenote: We had to pass wkix32.exe kixtart.kix to get it to work, which is kinda odd. |
||||||||
|
|
|||||||
What... no 2012 R2 native domain? LOL |
||||||||
|
|
|||||||
Oi Ron, seems to be the case, yes ... irdc Apart from that Allens function does work (see last post on page 2) |
||||||||
|
|
|||||||
Thanks Jochen for the feedback. I'll post it up to the UDFs soon. In the header I would like to include an example of how it is used in a GPO script. Did you do anything different than the normal (%Scriptdir%\kix.exe,Scriptname.kix)? |
||||||||
|
|
|||||||
Hi Allen, as our AD guy is on a 4 week vacation in the states, and none of the others is involved in that, I'll have to verify myself. If time allows, I'll post you an update on this soon, this week, probably even.. Yes! |
||||||||
|
|
|||||||
Oi Allen, been a long time, but fear not, I shan't forget thee! Ok, he tested successfully as GPO script ...\sysvol\blah\etc.. : Seems odd, but he did not manage to get it to run without the script parameter, so he had to make it as stated: wkix32 kixtart.kix oh yeah, and as already stated on page 2 of this thread it runs asynchroneously (which is totally ok for our needs) Anything else? |