How to run a .bat with UNC paths to other servers as admin across all servers

Ken Ski 21 Reputation points
2022-02-04T14:23:35.05+00:00

Hello PowerShell Community,

First time asking a question. I have been tasked to execute a .bat script written by Hyperion that issues start/stop "sc.exe" commands across 4 servers.

If I manually run the script with the hyperion account "As Admin" from the server where the .bat files exist, the command works perfectly.

When I try to run the .bat script from powershell with a {Start-Process -FilePath D:\Oracle\Scripts\Hyp_Services_stop.bat -Verb RunAs -Wait} command remotely, the command partially works on the server where the .bat resides, but gets a "[SC] OpenSCManager FAILED 5: Access is denied." error.

If the .bat script is running as Administrator why does the command only work locally?

The commands in the .bat script look like this:

echo stopping Financial Reporting services. %date% %time% >> %LOGFILE%

sc \ServerNameHere.domain.com stop "HyS9FRReports_epmsystem1"
choice /n /t 5 /d y > nul

I'm attaching the script I have written. Any suggestions would be greatly appreciated.171385-hyperionscript.txt

Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,343 questions
0 comments No comments
{count} votes

Accepted answer
  1. MotoX80 31,556 Reputation points
    2022-02-07T15:17:11.217+00:00

    When Get-Service is used there are limitations on what is returned

    What's the problem?

    PS C:\> get-service -Name LanmanServer
    
    Status   Name               DisplayName
    ------   ----               -----------
    Running  LanmanServer       Server
    
    
    PS C:\> get-service -DisplayName Server
    
    Status   Name               DisplayName
    ------   ----               -----------
    Running  LanmanServer       Server
    
    
    PS C:\> get-service -DisplayName Server | Format-List -Property *
    
    
    Name                : LanmanServer
    RequiredServices    : {SamSS, Srv2}
    CanPauseAndContinue : False
    CanShutdown         : False
    CanStop             : True
    DisplayName         : Server
    DependentServices   : {RAPSService, Browser}
    MachineName         : .
    ServiceName         : LanmanServer
    ServicesDependedOn  : {SamSS, Srv2}
    ServiceHandle       : SafeServiceHandle
    Status              : Running
    ServiceType         : Win32OwnProcess, Win32ShareProcess
    StartType           : Automatic
    Site                :
    Container           :
    

4 additional answers

Sort by: Most helpful
  1. Rich Matheisen 44,456 Reputation points
    2022-02-04T16:12:45.267+00:00

    When you run that script manually, do you use "Run as administrator"? If you do, are you prompted by UAC to confirm that it's okay to run it?

    When you run the script on the remote machine you're probably (well, likely) encountering the same UAC challenge -- except you're never going to see it. Since nobody confirms that running the script is okay, the challenge fails.

    That's not a PowerShell problem, it's a security decision you have to make -- continue using UAC, modify how UAC is configured, or stop using UAC.

    0 comments No comments

  2. MotoX80 31,556 Reputation points
    2022-02-04T16:50:34.66+00:00

    This is the infamous double hop problem. From Desktop1 you are doing an Invoke-Command to Server1. That authentication works. But the bat file you execute then reaches out to other servers via "sc \servername". That is the double hop and that authentication fails.

    One workaround for your situation would be to define a scheduled task that runs the D:\Oracle\Scripts\Hyp_Services_stop.bat
    file. Define that task without any triggers and set it to run as your Hyperion admin account. You will need to enter that account's password when you define the task so that it can authenticate to all of the other servers. (You are effectively simulating logging on with that account and running the bat interactively.)

    Then in the scriptblock that the Invoke-Command executes, you would issue a "Start-ScheduledTask -TaskName" to kick off the task.

    The downside to that option is that if the password for the account changes, you will need to update that for the scheduled task.

    Your other alternatives are to use the ConfigurationName parameter....

    https://www.ipswitch.com/blog/the-infamous-double-hop-problem-in-powershell

    ..or the credSSP solution.

    https://devblogs.microsoft.com/scripting/enable-powershell-second-hop-functionality-with-credssp/

    If you use either of those 2 solutions, I recommend just calling cmd.exe directly and not use Start-Process. That way any stdout/stderr that is not captured in the log file will be returned in the Invoke-Command.

    $PlanningCommand = {cmd.exe /c D:\Oracle\Scripts\Hyp_Services_start.bat }
    
    0 comments No comments

  3. Ken Ski 21 Reputation points
    2022-02-07T15:11:14.207+00:00

    Hello Friends!!

    Double Hop was the issue. I ended up creating a new script that just issues an Invoke-Command to each server involved. Now I'm having an issue with the Get-Service command. When the sc.exe command is used it returns the fully qualified Name and DisplayName. When Get-Service is used there are limitations on what is returned in these fields.

    Does anyone have a suggestion on how to return the fully qualified NAME and DisplayName? Of a sample of how I can execute "sc.exe query"?

    Thanks.
    Ken Ski

    0 comments No comments

  4. Ken Ski 21 Reputation points
    2022-02-07T23:04:00.82+00:00

    @MotoX80 Last question for this challenge I have undertaken.

    How do I redirect the "VERBOSE" message to an outfile?

    I have found many examples on how to pipe to an out-file, or redirect using variations of (4>&1), (*>&1), but none have worked for me.

    The Invoke-Command is writing to my outfile, but the Scriptblock command is writing into the spool file of the job I execute. I would like all the messages written into my outfile.

    172036-image.png

    Thank you in advance.
    KenSki