Results 1 to 11 of 11
  1. #1
    Super Moderator BATcher's Avatar
    Join Date
    Feb 2008
    Location
    A cultural area in SW England
    Posts
    3,414
    Thanks
    33
    Thanked 195 Times in 175 Posts

    Task-scheduling a BATch file to run as Administrator

    I am trying to get a BATch file containing a REGEDIT command line to run ONCE at Logon time in elevated mode=as Administrator in each user account (standard user, not Administrator) on a whole bunch of Windows 7 Pro PCs in a workgroup.

    As the final step of the BATch file I want to create a flag file which contains the name of the standard user who has just logged on, so that it can be checked in the first step of the BATch file, with the remainder of the BATch file to be ignored if it has already run once for that user, in that PC.

    However, one of the problems of running a BATch file in Elevated Mode=as Administrator, is that all the environment variables (such as %username%, %userprofile%, etc) relate to the Administrative User under which the BATch file ran, NOT the original Standard User who logged on!

    Does anyone know of a way to obtain the name of the logged-on Standard User from within the "elevated mode" BATch file?
    Or can suggest another "minimum effort" way of doing this once-only-per-standard-user-logon function?

    Thanks!

    PS I don't have a problem with the Task Scheduling, which works wonderfully - once you can get SCHTASKS to do what you want...!
    Last edited by BATcher; 2016-02-22 at 09:33. Reason: Add PS
    BATcher

    Time prevents everything happening all at once...

  2. #2
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    BATcher,

    How about running a Scheduled task as a standard user, grabbing the environment variables you need then have it call a Scheduled Task set for Run on Demand and As Administrator passing in the captured values as arguments?

    It may also be possible via PowerShell if you would like me to mess with it? If so, what environment variables do you need?

    HTH
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  3. #3
    WS Lounge VIP
    Join Date
    Dec 2009
    Location
    Earth
    Posts
    8,175
    Thanks
    47
    Thanked 982 Times in 912 Posts
    Copy the required user values to a file and your scheduled task can read the values from the file.

    cheers, Paul

  4. #4
    Super Moderator BATcher's Avatar
    Join Date
    Feb 2008
    Location
    A cultural area in SW England
    Posts
    3,414
    Thanks
    33
    Thanked 195 Times in 175 Posts
    I'm still desperately clinging to the notion that there may be something in HKCU which holds the username (which is all I want) of the original "standard user".

    RG's idea, as modified by Paul's, has much merit but I haven't got my head round how one scheduled task can call another. A quick Google didn't find me anything I could understand!

    If I can get this to work, even though having two tasks might be more complicated, the work of identifying whether REGEDIT has run once before for this user, or not, can be handled in the first task, and the second task, to run REGEDIT as Administrator, would be called only if the answer is No.
    BATcher

    Time prevents everything happening all at once...

  5. #5
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    Batcher,

    Here's the command syntax for calling a Scheduled Task from a shortcut (same as from a .bat file).

    C:\Windows\System32\schtasks.exe /run /TN "your task name here"

    HTH
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  6. #6
    Super Moderator BATcher's Avatar
    Join Date
    Feb 2008
    Location
    A cultural area in SW England
    Posts
    3,414
    Thanks
    33
    Thanked 195 Times in 175 Posts
    Thanks! I was using SCHTASKS /Create to set up the scheduled task anyway (and /Query and /Delete), but I'd forgotten about the /Run parameter. Dough!
    BATcher

    Time prevents everything happening all at once...

  7. #7
    WS Lounge VIP
    Join Date
    Dec 2009
    Location
    Earth
    Posts
    8,175
    Thanks
    47
    Thanked 982 Times in 912 Posts
    Bread?!

    cheers, Paul

  8. #8
    4 Star Lounger
    Join Date
    Jan 2010
    Location
    Fort McMurray, Alberta, Canada
    Posts
    557
    Thanks
    51
    Thanked 68 Times in 66 Posts
    Does anyone know of a way to obtain the name of the logged-on Standard User from within the "elevated mode" BATch file?
    I'm not sure how to do exactly what you're saying, but I'm also not sure that's the best goal. If you are making user specific registry changes, there's no way to identify the "main" or "usual" account. I know that I routinely have Help Desk accounts on my computer even though they only log on to fulfill requested work.

    So what do do? I'd cheat, and here's how I'd do it. Each account gets a folder in the C:\Users folder. Therefore all you need to do is to perform a Dir command in C:\Users and you have a list of all the local user accounts.

    The trick is that there are some standard entries in C:\Users. These appear on any system and you probably don't want to process registry changes for them. Entries like Public and possibly also Administrator. You must therefore exclude such standard folders using whatever mechanism you find appropriate.

  9. #9
    Super Moderator BATcher's Avatar
    Join Date
    Feb 2008
    Location
    A cultural area in SW England
    Posts
    3,414
    Thanks
    33
    Thanked 195 Times in 175 Posts
    Thanks, RG. Unfortunately I have run out of time to get the primary scheduled task to run interactively (after the REGEDIT I need to run the previously-installed IE11). I have to have all 60 PCs with about five accounts in each done by first thing on Monday, so I am having to do it 'manually' in each account in each PC.

    But in the future it's quite likely that the (slightly-modified-with-experience) REGEDIT file will need to be rerun, and this time it needn't be interactive since there's no need to run IE11 at that point.

    So when I get time I'll begin work on this again.

    BHarder: exactly the same REGEDIT file gets applied to each user account.

    My pseudocode for each required user on the current PC goes as follows:
    1) Task Scheduled task ONE gets run as standard user on logon of this user
    2) Check flag file which incorporates %username%
    3) if it's present, then we have previously done the work for this user - exit task ONE immediately
    4) if it's absent, create the flag file incorporating %username%, and run scheduled task TWO which, interactively in Administrator mode, runs the REGEDIT and calls IE11
    BATcher

    Time prevents everything happening all at once...

  10. #10
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    BATcher,

    Bummer! I'm still working on this though as It has me curious. I keep running into road blocks (lack of knowledge mostly I'm sure) but I'll keep plugging.
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

  11. #11
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    9,434
    Thanks
    372
    Thanked 1,457 Times in 1,326 Posts
    BATcher,

    By Jove I think I've got it!

    This was a bit tricky but I seem to have a working process:
    1. Create a PowerShell (PS) program to capture Logged-in User Info and write to file in C:\Users\Public ... will be overwritten each time program is run.
    2. Create a PS program to be run as Administrator that will read the previously written file, compare against log file to see if already done, if not proceed to make changes (didn't write this part), then write to a log file (located on the network, in my case a NAS) the fact that the deed has been done.
    3. Create a scheduled task to be run at Logon by ANY user that will run the PS program in item 1.
    4. Create a scheduled task to be run at Logon + 30 seconds that will run the second PS program as Administrator {with highest privleges}. I had to do it this way because trying to call a Scheduled Task that was established by an Administrator doesn't work, at least by any means I could discover.


    WhoCalled.ps1
    Code:
    #<   ---- Sample File Output ---
    Mickey
    C:\Users\Mickey
    >#
    
    $CallingUser = $env:USERNAME
    $CallingProfile = $env:USERPROFILE
    $OutputFile = "C:\Users\Public\WhoCalled.txt"
    
    $CallingUser > $OutputFile
    $CallingProfile >> $OutputFile
    
    #C:\Windows\System32\schtasks.exe /run /TN "AdminLogonProc#
    $CallingUser = $env:USERNAME
    $CallingProfile = $env:USERPROFILE
    $OutputFile = "C:\Users\Public\WhoCalled.txt"
    
    $CallingUser > $OutputFile
    $CallingProfile >> $OutputFile
    ElevatedProcess.ps1
    Code:
    Function Get-AdminStatus {
    
        If (-NOT ([Security.Principal.WindowsPrincipal] `
              [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
              [Security.Principal.WindowsBuiltInRole] "Administrator"))
        {"User"}
        Else
        {"Administrator"}
    }      # End Get-AdminStatus
    
    $WhoCalled = Get-Content "C:\USERS\Public\WhoCalled.txt"
    $CallingUser = $WhoCalled[0]
    $CallingProfile = $WhoCalled[1]
    
    $ErrorActionPreference = "SilentlyContinue"
    $ProcessedLog = "\\MYBOOKLIVE\CMShared\AdminLog\Processed.log"
    $ErrorActionPreference = "Continue"
    
    $FoundUser = Get-Content $ProcessedLog | 
                 Select-String -Pattern "Called by: $CallingUser "
    
    If ($FoundUser.Count -eq -0) {  #Not Previously Processed
    
      $CurrentUser = $env:UserName
      $CurrentProfile = $env:UserProfile
      $IsAdmin = Get-AdminStatus
    
      $TimeStamp = get-date -f "MM/dd/yyyy HH:mm:ss"
    
      "$TimeStamp Called by: $CallingUser " +
         "ProfilePath: $CallingProfile" >> $ProcessedLog
      "$TimeStamp Run As   : $CurrentUser " + 
         "ProfilePath: $CurrentProfile Permissions: $IsAdmin" >> $ProcessedLog
    
    } #End If (FoundUser.Count...
    Here are the sample scheduled task in XML format suitable for importing into the Task Scheduler once the appropriate edits have been made. Note: these need to be created with the admin account!

    Task Definition for WhoCalled.ps1
    Code:
    <?xml version="1.0" encoding="UTF-16"?>
    <Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
      <RegistrationInfo>
        <Date>2016-02-24T12:19:23.0572017</Date>
        <Author>Administrator</Author>
        <URI>\LogonProc</URI>
      </RegistrationInfo>
      <Triggers>
        <LogonTrigger>
          <Enabled>true</Enabled>
        </LogonTrigger>
      </Triggers>
      <Principals>
        <Principal id="Author">
          <GroupId>S-1-5-32-545</GroupId>
          <RunLevel>LeastPrivilege</RunLevel>
        </Principal>
      </Principals>
      <Settings>
        <MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy>
        <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
        <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
        <AllowHardTerminate>true</AllowHardTerminate>
        <StartWhenAvailable>true</StartWhenAvailable>
        <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
        <IdleSettings>
          <StopOnIdleEnd>true</StopOnIdleEnd>
          <RestartOnIdle>false</RestartOnIdle>
        </IdleSettings>
        <AllowStartOnDemand>true</AllowStartOnDemand>
        <Enabled>true</Enabled>
        <Hidden>false</Hidden>
        <RunOnlyIfIdle>false</RunOnlyIfIdle>
        <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
        <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
        <WakeToRun>false</WakeToRun>
        <ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
        <Priority>7</Priority>
      </Settings>
      <Actions Context="Author">
        <Exec>
          <Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
          <Arguments>[d:\path]\WhoCalled.ps1</Arguments>
        </Exec>
      </Actions>
    </Task>
    Task Definition for ElevatedProcess.ps1
    Code:
    <?xml version="1.0" encoding="UTF-16"?>
    <Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
      <RegistrationInfo>
        <Author>DELLXPS14Z\Bruce</Author>
        <Description>No Description Supplied</Description>
        <URI>\AdminLogonProc</URI>
      </RegistrationInfo>
      <Triggers>
        <LogonTrigger>
          <Enabled>true</Enabled>
          <Delay>PT30S</Delay>
        </LogonTrigger>
      </Triggers>
      <Principals>
        <Principal id="Author">
          <UserId>S-1-5-21-576607286-1355931187-1668288886-1002</UserId>
          <LogonType>Password</LogonType>
          <RunLevel>HighestAvailable</RunLevel>
        </Principal>
      </Principals>
      <Settings>
        <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
        <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
        <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
        <AllowHardTerminate>true</AllowHardTerminate>
        <StartWhenAvailable>false</StartWhenAvailable>
        <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
        <IdleSettings>
          <StopOnIdleEnd>false</StopOnIdleEnd>
          <RestartOnIdle>false</RestartOnIdle>
        </IdleSettings>
        <AllowStartOnDemand>true</AllowStartOnDemand>
        <Enabled>true</Enabled>
        <Hidden>false</Hidden>
        <RunOnlyIfIdle>false</RunOnlyIfIdle>
        <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
        <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
        <WakeToRun>false</WakeToRun>
        <ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
        <Priority>7</Priority>
      </Settings>
      <Actions Context="Author">
        <Exec>
          <Command>"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"</Command>
          <Arguments>"[d:\path]\ElevatedProcess.ps1"</Arguments>
        </Exec>
      </Actions>
    </Task>
    Here is what the Log file looks like:
    Code:
    02/24/2016 15:11:42 Called by: Mickey ProfilePath: C:\Users\Mickey
    02/24/2016 15:11:42 Run As   : Mickey ProfilePath: C:\Users\Mickey.DELLXPS14Z Permissions: Administrator
    02/24/2016 15:13:50 Called by: Minnie ProfilePath: C:\Users\Minnie
    02/24/2016 15:13:50 Run As   : Mickey ProfilePath: C:\Users\Mickey.DELLXPS14Z Permissions: Administrator
    Notes:
    • I see no reason why the PS programs can not be located on a network drive although I didn't try this.
    • PS allows easy access to the Registry via the PSDrive functionality.
    • I tried the Task for ElevatedProcess with both a 1 minute and 30 second delay and had no problem on my machine with the 30 second delay. YMMV
    • Don't forget to replace the parts highlighted in Blue with the location where you placed the PS programs.



    HTH
    May the Forces of good computing be with you!

    RG

    PowerShell & VBA Rule!

    My Systems: Desktop Specs
    Laptop Specs

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •