Task Breaking: Microsoft Windows 2012R2, Task Scheduler, Excel 2013 VBScript - excel

I am trying to move some Excel automation Tasks (Task Scheduler) from an older (Win2003) server to a new Windows 2012 R2 server.
I can get it to work when I first create the task, but if I change anything it stops working and I can't figure out why, or how to stop it from changing. Any thoughts? (also see my second observation below)
Here's What Happens
I create the initial task as shown below and it works fine, but if I change the user that the script runs as, It fails with the error:
Cannot run the macro 'Build'. The macro may not be available in this workbook or all macros may be disabled.
Changing the task to run as the original (working) user does not fix it. I get the same error when I re-run the task and have to delete/re-create it to get it to run again.
File/Task Details
D:\ApplicationDir\run.wsf (simplified)
<job id="1">
<script language="VBScript">
On Error Resume Next
Dim excel
Dim SourceFile
Set excel = CreateObject("Excel.Application")
SourceFile = "D:\ApplicationDir\File.xlsm"
excel.Workbooks.Open SourceFile
excel.Run "Build"
excel.Workbooks.Close
If Err <> 0 Then
... write Err.Description to file ...
End If
Set excel = Nothing
</script>
</job>
Task (in Task Scheduler)
- Runs as a user Account
- Run whether user is logged on or not
- Run with highest privileges
- Configure For: Windows Server 2003, Windows XP or Windows 2000
Triggers:
- Daily At 6:15 AM every day
Actions:
- Start a Program:
- Program: C:\Windows\System32\cscript.exe
- Arguments: run.wsf
- Start In: D:\Application_Dir\
Another Observation
If I select any other "Configure for:" option, I lose the ability to select "Windows Server 2003, Windows XP or Windows 2000" altogether. The option just isn't there when I go back to edit the task properties. Any ideas why this is happening ?
Thanks in advance.

Related

Start OneDrive Under Full Admin Rights

Summary
I necessarily run Excel with Admin privileges and I have UAC set to Never Notify. Excel VBA opens Word. Word has a macro button that restarts OneDrive. The error message is that "OneDrive can't be run using full admin rights." How can I restart OneDrive without the error massage?
Note: There is a sister post at How to Restart OneDrive via VBA When Running Excel Elevated, but that post poses an entirely different question.
Workflow
Excel VBA opens Word:
Sub m_Test_Finish_WordDoc()
Const strpath = "C:\Users\ssttr\OneDrive\Documents\Investing\Automation\Static Inputs\Restart_OneDrive.docm"
Dim Wd As Object
Dim InstrDoc As Object
Dim f As Boolean
On Error Resume Next
Set InstrDoc = GetObject(strpath)
With InstrDoc.Parent
.Visible = True
.Activate
End With
End Sub
Word macro restarts OneDrive:
Private Sub CommandButton1_Click()
Application.Run "Restart_OneDrive"
End Sub
Sub Restart_OneDrive()
'Restarts OneDrive
Dim shell
Set shell = CreateObject("wscript.shell")
shell.Run """C:\Users\ssttr\OneDrive\Documents\Investing\Automation\Static Inputs\OneDrive Restart - Copy.bat""" 'bat.zzz
End Sub
Contents of OneDrive Restart - Copy.bat
REM Restarts OneDrive from the command line.
REM From https://stackoverflow.com/questions/29872973/syncing-onedrive-skydrive-with-batch-file-via-cmd.
REM If the /background switch is omitted then Explorer is opened to the OneDrive folder in your user profile but OneDrive does not start.
REM If restarting OneDrive from a batch file then add the START command or the batch file won't end.
REM start %LOCALAPPDATA%\Microsoft\OneDrive\OneDrive.exe /background <-- the original '~error-producing' command
RunWithRestrictedRights %LOCALAPPDATA%\Microsoft\OneDrive\OneDrive.exe -w -v
One Possible Path to a Solution
I downloaded the RunWithRestrictedRights.exe standalone executable from https://www.coretechnologies.com/products/RunWithRestrictedRights/ into the C:\Windows\System32 directory and the implementation (shown above) in VBA was replacing the
start %LOCALAPPDATA%\Microsoft\OneDrive\OneDrive.exe /background
line in my batch file (which BTW is from Syncing OneDrive (SkyDrive) with Batch File (via cmd))
with
RunWithRestrictedRights %LOCALAPPDATA%\Microsoft\OneDrive\OneDrive.exe.
Note that, as required at the very bottom of https://www.coretechnologies.com/products/RunWithRestrictedRights/, I added the Administrator to the security policy settings for "Replace a process level token" and for "Adjust memory quotas." See below Notes > SecPol.msc ยง.
The hang-up is when that the batch file, when called in the above process (Important: remember Excel is Run As Admin), runs (i.e. cmd window flashes) but it does not open OneDrive.
Is my problem, as I suspect, in my batch file, or somewhere else? If somewhere else, then you may wish to see my sister post (it is the same underlying issue but pursing a very different question) at How to Restart OneDrive via VBA When Running Excel Elevated.
Notes:
Things that didn't work for me:
There was some stuff about UAC being required relative to an elevated launch of OneDrive, but that's a non-starter for me because if a user needs to attend to a UAC prompt, then my code's purpose of full automation is negated. Also, for my purposes, I have UAC set to Never Notify.
From https://superuser.com/questions/171917/force-a-program-to-run-without-administrator-privileges-or-uac/450503#450503 -- The MS RunAsInvoker Application Compatibility Toolkit shim does not apply bc I have UAC turned off by default.
FWIW, I did try setting UAC to Always Notify but it did not remove the error. I also tried RunAs /trustlevel:0x20000 %LOCALAPPDATA%\Microsoft\OneDrive\OneDrive.exe, and it did not seem to work, which is because per https://www.coretechnologies.com/products/RunWithRestrictedRights/ I have UAC disabled.
Origins of the solution I am pursuing:
From https://www.coretechnologies.com/blog/alwaysup/onedrive-hates-admin-rights/ -- "UAC enables an administrator to run OneDrive normally" section -- this is a really informative and provided the final solution
SecPol.msc
From https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/replace-a-process-level-token -- "This policy setting determines which parent processes can replace the access token (editor's note - describes the security context of a process or thread) that is associated with a child process." That's the lynch pin setting.
I set that per https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment and https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/how-to-configure-security-policy-settings.
I also had to set Adjust memory quotas for a process per https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/adjust-memory-quotas-for-a-process and https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/how-to-configure-security-policy-settings.
Per https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/how-to-configure-security-policy-settings, "any change to the user rights assignment for an account becomes effective the next time the owner of the account logs on." so I restarted (after I tested and confirmed it did not work without a restart).
Update 2022-01-07-18.7
I've moved from a *.bat because I was passing multiple commands, to attempting to directly implement the command by way of:
Sub Restart_OneDrive()
Dim RWRR As Variant
RWRR = shell("RunWithRestrictedRights.exe ""C:\Users\ssttr\AppData\Local\Microsoft\OneDrive\OneDrive.exe"" -w -p -v", vbNormalFocus)
End Sub
but I get Run-time error '53': File not found.
The error still occurs if I change to
RWRR = shell("C:/Windows/System32/RunWithRestrictedRights.exe ""C:\Users\ssttr\AppData\Local\Microsoft\OneDrive\OneDrive.exe"" -w -p -v", vbNormalFocus)
or to
Call shell("RunWithRestrictedRights ""C:\Users\ssttr\AppData\Local\Microsoft\OneDrive\OneDrive.exe""", vbNormalFocus)
I have the required security policy set per https://www.coretechnologies.com/products/RunWithRestrictedRights/ :
which states:
Does RunWithRestrictedRights.exe work on Windows XP and Windows Server
2003, where there is no UAC?
Yes, it works well on Windows XP and Windows Server 2003. The Windows
Integrity Level can't be set (that feature is only available in
Windows Vista and later) but the application is run without admin
rights as intended.
One note though: If you receive an error stating that "a required
privilege is not held by the client", please ensure that your account
has these two rights: Adjust memory quotas for a process; Replace a
process level token.
If I run directly from a non-elevated command line
RunWithRestrictedRights.exe "C:\Users\ssttr\AppData\Local\Microsoft\OneDrive\OneDrive.exe" -w -p -v
or
C:/Windows/System32/RunWithRestrictedRights.exe "C:\Users\ssttr\AppData\Local\Microsoft\OneDrive\OneDrive.exe"```` or ````RunWithRestrictedRights "C:\Users\ssttr\AppData\Local\Microsoft\OneDrive\OneDrive.exe" -w -p -v
it works, resulting in:
I have tried all these syntax commands inside the shell, with what I think are the appropriate syntax changes, e.g. as shown the above VBA above, but still get the run time error 53.
FWIW here's the help for RunWithRestrictedRights.exe:
which says:
RunWithRestrictedRights
Synopsis: Runs a given application in a "restricted" mode - at Medium
(or Low) Integrity and without rights granted by being a member
of the Administrators group.
Usage: RunWithRestrictedRights.exe [-w] [-l] [-p]
[-v]
[-d ]
Options:
The full path to the application to be started. Please be
sure to enclose the path in quotes if it contains at least
one space.
-w Instead of returning immediately after launching the
application, wait until the application ends. Optional.
-l Instead of running the application with Medium Integrity,
start it with Low Integrity. Optional.
-p Also strip away rights granted from being a member of the
"Power Users" group. Optional.
-d Also deny rights to the given SID.
-v Produce verbose output. Optional.
Exit code: The non-zero process identifier (PID) if the
application
was successfully started.
-1 if there was an error starting the application.
Version: 3.0.1.16 (Feb 18 2020)
Example: > RunWithRestrictedRights.exe "C:\MyApp\MyApp.exe"
- Starts MyApp.exe with retricted rights.
This free utility is Copyright 2020, Core Technologies Consulting,
LLC. Find out about this and our other products at our web site:
https://www.CoreTechnologies.com/

Why isn't my script able to locate my excel file when given correct filepath?

I have a .vbs script that opens two excel files and copies the contents of a sheet from the first file into the second file. It's supposed to run daily via task scheduler.
The script ran normally until the excel files in question were recently modified and slightly renamed - I went through the script and edited the filenames accordingly after the changes were made, triple checking that the names and filepaths matched up.
Everything ran fine for a few weeks after the changes but now the script fails immediately after starting, giving me an error claiming that the file can't be located even though the file is located at the given path. The error code is 800A03EC.
This is the first chunk of code in the script, including line 7 which seems to be throwing the error:
Dim objApp ' as excel object
Dim x, y ' as workbook
Set objApp = CreateObject("Excel.Application")
objApp.DisplayAlerts = False
objApp.Visible = False
Set x = objApp.Workbooks.Open("S:\Work (Public)\PORT MGMT & TRADING\PORT MGMT FORMS\ORION_FPFOCUS.xlsm")
Set y = objApp.Workbooks.Open("S:\Work (Public)\PORT MGMT & TRADING\PORT MGMT FORMS\FPFocusPasteSpecialValues.xlsb")
Dim WSx, WSy ' as excel worksheet
Set WSx = x.Worksheets("FPSUP")
Set WSy = y.Worksheets("FPFOCUS-COPY")
WSy.Range("B1").value = FormatDateTime(Now)
objApp.Application.Run "ORION_FPFOCUS.xlsm!Auto_Open"
The excel files in question are both located in the same directory:
S:\Work (Public)\PORT MGMT & TRADING\PORT MGMT FORMS\ORION_FPFOCUS.xlsm
S:\Work (Public)\PORT MGMT & TRADING\PORT MGMT FORMS\FPFocusPasteSpecialValues.xlsb
And the script is located here:
C:\Users\bserv\Documents\CopyFPFocus.vbs
The S drive isn't a physical drive, it's a virtual drive hosted by a service called Workplace. I can navigate through it and open the excel files manually just fine.
I initially thought it was a user privilege issue with task scheduler, but I've selected the 'run with highest privileges' option and the script is still failing. I also went through the privacy/trust settings in Excel to make sure the script wasn't being denied access, but I don't see any settings that would disable the script from working, and I also know that all these settings haven't changed since the script was working, so I don't see how they could be potential causes.
When I try running the code manually via cscript in the command line, it returns this error:
C:\Users\bserv\Documents\CopyFPFocus.vbs(25, 4) (null): The remote procedure call failed.
This is line 25 of the script for reference:
objApp.Run "RefreshAllStaticData"
When I try again by running command prompt as an admin, I get the same error I got initially. Sorry, is it possible the file was moved renamed or deleted.
The part that really confuses me is that the script ran fine for some time after the changes - so I'm really unsure about what actually changed to cause this issue to randomly pop up.
One other thing I've noticed is that upon opening the excel files I get a popup saying they're in use and locked for editing by me. I can't remember if this popup was showing up before the issue started. The other users on the network have been accessing these files regularly long before the script started failing, so I don't see how that could be the issue. The error code/message also doesn't seem to correspond with this being the problem.
I'd appreciate any help or insight into this issue. Thank you!

workbooks.add fails when vbs-script is called from Task Scheduler

I have some code in VBscript that creates an excel object and adds a workbook to it
Dim oExcel, oWB
Set oExcel = CreateObject("excel.application")
Set oWB = oExcel.Workbooks.Add()
When I run this myself (using VbsEdit or cscript), it has no issues and does the job.
When I make an entry in the Windows 10 Task-Scheduler (or Server 2019 too), run it with setting 'even if the user is offline', it fails with errorcode -2147023170. When I say the user MUST be online (useless, but I tried it anyway) then I get the error 1004 - Unknown runtime error.
I can't figure out what causes this. I presume it's a Office 365 issue, because on an older system (windows server 2012 R2 with office 2016) it runs just fine from the task scheduler.
The account it runs under is administrator, the task runs with the highest priority. The Vbs is not called directly, but using a bat-file with logging. Running a vbs-script directly from the task scheduler seems to get stuck at "running" indefinately :(
Who knows how to fix this ?
Thanks,
Paul
How about removing the brackets at the end of Workbooks.Add?
Set oWB = oExcel.Workbooks.Add

How to work around Excel 2016 halting without message when trying to assign variable to VBProject?

System Details.
Windows 10
Excel 365 64-bit V16.0 (Apps for Enterprise)
Issue.
I have a macro that opens a file, checks if the user has allowed programmatic access to the VBA Project in the trust center and raises an alert if they have not. This works fine on windows 7 machines with both 32bit and 64bit Excel from 2013 onwards.
The specific problem I am having on the Windows 10 machine is that when workbooks.open(path) is executed the file opens but in the VBA Project explorer window the VBAProject object for that file does not appear. I also get a popup saying that code cannot be run in break mode when I try this while stepping through the code. When run on Win 7 with this version of Excel and others both 32 and 64-bit the VBAProject object appears and no popup is generated.
This lack of the VBA Project causes an issue later when I run set vbproj = ActiveWorkbook.VBProject. At this point when stepping through the code execution halts with no messages at all. The Project pops up in the Project explorer window and it takes me to a module in the opened workbook. This gets opened with Design Mode turned on and when you click to turn it off I get an error message saying 'Macros have been disabled'
Notes
set vbproj = ActiveWorkbook.VBProject works fine if the file is open and the VBAProject is visible in the Project explorer window.
If the file being opened does not contain a macro then it works correctly.
I have made sure that the files are in a Trusted Location.
I have set Enable all macros in the Macro Settings of the Trust Center.
When opening the files manually I do not get any alerts that macros have been disabled by an administrator and I do not get any message asking if I want to enable macros.
I have looked at W10 group policies to see if there is one that would block VBAProjects / Macros from files opened via VBA and there does not appear to be one as far as I can see.
The Trust Center setting for programmatic access to the VBA Project does not matter to this test case. It will return True if it is allowed and False if it is not allowed.
This has been tested on another Windows 10 laptop with the same version of Excel 64-bit and it has the same result so is not an issue with a specific users laptop.
I removed the folder from the Trusted Location on the Windows 7 machine and the code still executes correctly and returns True/False.
In the actual macro this check is done for each opened file in a loop and the variant vbproj is used to remove data from the modules within that project. I have considered working around the issue by using Application.onTime and that may be a solution but have not spent much time on that and with how it halts it may not be viable.
Attempted Solutions
I have tried set wb = workbooks.open(path) to open the workbook and then using set vbproj = wb.VBProject but it has the same behavior as above.
I have tried doing ActiveWorkbook.Activate and similar actions to see if that will make the VBA project appear, it does not.
I have tried setting Application.FileValidation = msoFileValidationSkip before opening the file, this does not change the behavior.
I have tried setting Application.EnableEvents=False before opening the file, this does not change the behavior.
I have tried making vbproj a variant, an object and a VBProject, this does not change the behavior.
Steps to Recreate
Create a new workbook.
Put the below code into Module 1.
Function projectAccess()
Dim vbproj As Variant
On Error GoTo noaccess
Set vbproj = ActiveWorkbook.VBProject 'If access is denied an error is raised.
projectAccess = True
Exit Function
noaccess:
projectAccess = False
End Function
Sub openfile()
Dim filepath As String
filepath = Application.ThisWorkbook.Path
Workbooks.Open (filepath & "\openfile.xlsm")
Debug.Print projectAccess
End Sub
Save the workbook
Create a 2nd workbook, in my case it was called openfile.xlsm and put some code into Module 1.
put both workbooks in the same location and make sure it is a Trusted Location in Excel.
run openfile().
If successful the immediate window will display True / False depending on the Trust Center setting.
I am out of ideas. Any suggestions for some setting that I may have overlooked to make the Win 10 machines behave the same as the Win 7 machines or suggestions for a possible work around?
Even if it is a group policy setting that would be something I can raise with IT as long as I know what to ask for.
Many Thanks
Andrew
EDIT: Thanks to Rory in the comments the issue was making sure that the automation security was set like so Application.AutomationSecurity = msoAutomationSecurityLow as the way the new Win 10 + Office 64 systems have been set up by my IT dept is to have it default to msoAutomationForceDisable

Task Scheduler does not Run the Task

As the title says, I am trying to get the Task Scheduler to do as follows:
Open an specific Excel file at an specific time every day and run the module 1 within said file.
The workbook name is Daily Invoiced, and it contains a Macro, therefore the file is an xlms. The code I need to run is in the Module 1, therefore this is the one that needs to be selected.
This file is stored in my folder C:\Users\MartiJor1\Documents\MACROS\Daily Invoiced.
What have I done so far?
Followed the example listed in https://www.thespreadsheetguru.com/blog/how-to-automatically-run-excel-vba-macros-daily where the plan is to use a Script. Here is what mine ends looking like:
'Input Excel File's Full Path
ExcelFilePath = "C:\Users\MartiJor1\Documents\MACROS\Daily Invoiced ZAMSOTC02 LAC TEAM.xlsm"
'Input Module/Macro name within the Excel File
MacroPath = "Module1.LAC_Daily_Invoiced_Report"
'Create an instance of Excel
Set ExcelApp = CreateObject("Excel.Application")
'Do you want this Excel instance to be visible?
ExcelApp.Visible = True 'or "False"
'Prevent any App Launch Alerts (ie Update External Links)
ExcelApp.DisplayAlerts = False
'Open Excel File
Set wb = ExcelApp.Workbooks.Open(ExcelFilePath)
'Execute Macro Code
ExcelApp.Run MacroPath
'Save Excel File (if applicable)
wb.Save
'Reset Display Alerts Before Closing
ExcelApp.DisplayAlerts = True
- Note: If I execute the script with the Windows Based Script Host, it runs smoothly.
I also used the rest of the configuration suggested in the article for the script to run, except I am using Windows 10 Pro. However, nothing happens at the scheduled hour, nor when I run it manually. On the Last Run Result I can see the code (0x41303) which is an error code related to a date in the past. Does not matter how many times I amend it for the near future, it does not run.
I can not see the error. I believe it must be somewhere in the Actions Tab, and I arrive to this conclusion by the fact that I can run the Script with the Windows Based Script Host as mentioned above. Any idea guys?
Here is also the script from the Task when I export it:
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2020-10-31T21:41:26.1715916</Date>
<Author>GUWW\MartiJor1</Author>
<Description>Test</Description>
<URI>\DailyInvoiced</URI>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2020-11-02T14:03:00</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>S-1-12-1-4092016482-1174842289-577708437-4023581491</UserId>
<LogonType>Password</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>true</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>true</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
<RestartOnFailure>
<Interval>PT1M</Interval>
<Count>3</Count>
</RestartOnFailure>
</Settings>
<Actions Context="Author">
<Exec>
<Command>"C:\Windows\System32\cscript.exe"</Command>
<Arguments>"C:\Users\MartiJor1\Documents\MACROS\Daily.vbs"</Arguments>
</Exec>
</Actions>
</Task>
Thanks in advance.

Resources