Within Power Automate Desktop, I can create an action to run a VBScript.
For example, if I have created a variable CurrentDate with the
Get current date and time action, then the following script in
a VBScript action will generate output in a text variable in PAD:
VBTest = 3
WScript.Echo VBTest
WScript.Echo "%CurrentDate%"
WScript.Echo "Year %CurrentDate.Year%"&" DOW %CurrentDate.DayOfWeek%"
Output captured in variable:
3
12/5/21 12:00:00 AM
Year 2021 DOW Sunday
But what is the version of the scripting engine used, and how can I get
more info about what is available?
Documentation about VBScript (which is no longer actively updated
by Microsoft, it cannot even by found in the product life cycle
search) can be found under previous versions of Internet Explorer.
Running the following VBScript in Power Automate Desktop 2.14 reveals
the scripting engine "VBScript Version 5.8.16384".
Function GetScriptEngineInfo
Dim s
s = "" ' Build string with necessary info.
s = ScriptEngine & " Version "
s = s & ScriptEngineMajorVersion & "."
s = s & ScriptEngineMinorVersion & "."
s = s & ScriptEngineBuildVersion
GetScriptEngineInfo = s ' Return the results.
End Function
WScript.Echo GetScriptEngineInfo
Related
I used to run 3 SAS EG Projects on a daily basis. Since a couple of days, we have a "SAS Scheduler" that is basically running those latter during the night (the first one at 00:00 AM, second one at 01:00 AM, third one at 03:00 AM). Each SAS Project has multiple SAS Programs.
All in all, that is great news, but this also mean I can't check the logs directly anymore.
To keep track of the night jobs, I am trying to find what could be the best way to export the log files for each project. I found out about the SAS Project Log recently, which basically summarize the logs from all the programs within a SAS Project.
I discovered CaseySmith's answer on the SAS Community forum, basically tweaking the .vbs script to save the SAS Project log file to a .txt using the following code:
Set objProjectLog = objProject.ProjectLog
objProjectLog.Clear()
objProjectLog.Enabled = True
'strProjectLog = objProjectLog.Text
objProjectLog.SaveAs "c:\temp\projectLog.txt"
But, 1) It is a .txt file not a log file and 2) I don't know where to add it in my current .vbs script:
Option Explicit
Dim app
Call dowork
'shut down the app
If not (app Is Nothing) Then
app.Quit
Set app = Nothing
End If
Sub dowork()
On Error Resume Next
'----
' Start up Enterprise Guide using the project name
'----
Dim prjName
Dim prjObject
prjName = "C:\Users\kermit\Desktop\Project.egp" 'Project Name
Set app = CreateObject("SASEGObjectModel.Application.8.1")
If Checkerror("CreateObject") = True Then
Exit Sub
End If
'-----
' open the project
'-----
Set prjObject = app.Open(prjName,"")
If Checkerror("app.Open") = True Then
Exit Sub
End If
'-----
' run the project
'-----
prjObject.run
If Checkerror("Project.run") = True Then
Exit Sub
End If
'-----
' Save the new project
'-----
prjObject.Save
If Checkerror("Project.Save") = True Then
Exit Sub
End If
'-----
' Close the project
'-----
prjObject.Close
If Checkerror("Project.Close") = True Then
Exit Sub
End If
End Sub
Function Checkerror(fnName)
Checkerror = False
Dim strmsg
Dim errNum
If Err.Number <> 0 Then
strmsg = "Error #" & Hex(Err.Number) & vbCrLf & "In Function " & fnName & vbCrLf & Err.Description
'MsgBox strmsg 'Uncomment this line if you want to be notified via MessageBox of Errors in the script.
Checkerror = True
End If
End Function
In the end, what I would like is that on the morning, I run a program that scan the 3 project log files for Notes, Warning and Errors and send to myself an email with the results. Hence, is there a way to export the SAS Project Log (not manually) in a folder?
So, first, what is this code doing?
Set objProjectLog = objProject.ProjectLog
objProjectLog.Clear()
This clears the project log. This needs to be done before your project is run - otherwise the log contains data from past runs. So put this before the prjOBject.Run().
objProjectLog.Enabled = True
'strProjectLog = objProjectLog.Text
objProjectLog.SaveAs "c:\temp\projectLog.txt"
This then exports the project log to a text file. You of course can call that text file whatever you want. You need this code to appear after your program runs, and somewhere before it closes. Right after PrjObject.Run() is probably fine.
You will need to update the names to match your vbs file's names - they use objproject and your vbs uses prjObject, but those are the same thing, just match the names.
Second - what else could you do? If VBS isn't your thing, you have a lot of other ways you could do this.
Export your EG project to a .sas file, then schedule this in base SAS with the normal output options. This may also be possible via the scheduling interface.
Use PROC PRINTTO to redirect your log inside your SAS code.
Copy your EG project to a location you can see. The EG project does contain the log of everything that was run - so there's no reason you couldn't just open the .egp and look at it, just make sure you're not doing that with the production file since you might forget to close out.
My preference is not to schedule EG projects, but to schedule .sas programs; use EG as the development environment and then export to .sas. This gives you more flexibility. But there are a lot of different ways to skin this cat.
I have a excel macro working on Excel on my PC, but now I tried to get it working on my new Mac with Excel 2016.
Basically it saves the actual File based on a Field in the Workbook and the actual date.
Then it saves the same file as pdf.
When I exceute the script I get a runtime error that the file cannot be saved, pointig on the line where "SaveAs"... is located.
I think this has to do with the variables in the filename, because a fixed filename is woking...
Sub save_pdf()
Dim nr, jahr, jahreszahl, stdPfad, Dateiname
jahreszahl = Year(Now)
stdPfad = "Users/**myname**/Dropbox/Buchhaltung & Steuer/Customer/Zeiterfassung/" & jahreszahl & "/" & Format(Now, "mmmm") & "/"
Dateiname = stdPfad & "Zeiterfassung " & " " & Format(Now, "mmmm ") & [Projekt] & " " & Format(Now, "ddmmyyyy")
ActiveWorkbook.SaveAs Filename:=Dateiname
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=Dateiname _
& ".pdf", Quality:= _
xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=False
End Sub
Can someone push me in the right direction?
First of all, could you please, post here the text of the error? My first guess is that the writing permissions for that folder lead to this error. You could do something like this from the terminal:
chmod 777 Users/**myname**/Dropbox/Buchhaltung & Steuer/Customer/Zeiterfassung
Note that this command adds full permissions (Read, Write, Execute) for every user of your computer for that folder.
Office/Excel 2016 for Mac does not appear to have access to all folders. Saving to path /Users/username/Library/Group Containers/UBF8T346G9.Office/file_name.pdf worked for me, as mentioned here by Kamlesh: Unable to save as PDF from VBA in mac
I'm trying to use either wshShell.Exec or wshShell.Run to run a script through another script. I have tried both methods, and both methods give me the same error. I've Googled the issue and can't find anything that seems to fix the issue. The only suggestion that really was very relevant was to try using wshShell.Run instead of Exec.
Here's the relevant part of my script:
strScriptPath = "T:\IT resources\Scripts\Shutdown Scripts"
strForceShutdown = "ForceShutdown.vbs"
For j = 0 to 99
Set objActive = wshShell.Run(strForceShutdown)
' In case I ever need to get this working to run it from another folder.
' Set objActive = wshShell.Exec("cd " & strScriptPath & "")
' Set objActive = wshShell.Exec("wscript " & strForceShutdown & "")
constConf = MsgBox("Automatic shutdown initializing. Continue?" & chr(10) & "Y=Shutdown N=Postpone 30 minutes",4,"Automatic Shutdown Notification")
If constConf = 7 Then
objActive.Terminate
Wscript.Sleep(1800000)
Else
objActive.Terminate
Exit For
End If
Next
Thanks for any help!
Shell.Run returns an integer, so you can't call a method (Terminate) on its return value. You also can't Set it since it's not an object.
You can call your shutdown script by just running it. Give it the full path, however, not a relative path. Scripts launched from Task Scheduler often have different "starting folders" than those launched manually so don't rely on your script finding the other one relatively.
Also, you'll have to add Chr(34) before and after your path to account for any spaces.
strForceShutdown = "c:\path\to\ForceShutdown.vbs"
wshShell.Run Chr(34) & strForceShutdown & Chr(34)
Finally, why launch the script and then ask whether to shutdown? Why not just launch your script after the user has responded and then you don't have to worry about terminating a running process.
I am very new to vb script and i need a script to delete couple of thrid level subfolders based on starting name _SA and 2 days old
example
C:\abc\user1\temp\ _SA123
c:\abc\user2\temp_SA2345
c:\abc\user3\temp_SA4567
I want to delete the folder starting with _SA older than 2 days and I have 50+ users folder. please hlep
Thanks,
Chilli
Based upon the example data, this should work though I'd consider this the 4th level:
Edit: Because you asked nicely, I updated this to build a log in a variable that will list the path of the folder deleted, the date it was created, and the date you deleted it. This information shows up in a msgbox, but you could easily modify to print the data to a file instead.
Dim rootFolder
Dim fld
Dim subFld
Dim subsubFld
Dim Log
Set fso = CreateObject("Scripting.FileSystemObject")
Set rootFolder = fso.GetFolder("C:\abc\")
For Each fld In rootFolder.SubFolders
For Each subFld In fld.SubFolders
For Each subsubFld In subFld.SubFolders
If Len(subsubFld.Name) >= 3 Then
If Left(subsubFld.Name, 3) = "_SA" And subsubFld.DateCreated < Now() - 2 Then
Log = subsubFld.Path & ", Created " & subsubFld.DateCreated & ",Deleted" & Now & vbNewLine
subsubFld.Delete
End If
End If
Next
Next
Next
MsgBox Log
'Or you could print the log to a file.
It has no error trapping, (other than making sure the folder name is atleast 3 characters long) and will get permission denied if you don't have permission.
Note: the code I posted has indentations, it's just not display for some reason. If you want to see the indented code, hit the edit button.
I have created a VBS script in Windows. I will run this script to get size of a file.
I made this to run for ever. (even this is my requirement).
How should I know if it is running or stopped?
------ Exact Script starts here -----
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FSO_check=CreateObject("Scripting.FileSystemObject")
do while infiniteLoop=0
----- This code is lasting for ever ----
Loop
Am i clear in my ques?
How about using the commandline property? I think this need Windows XP and up.
For example:
Set objSWbemServices = GetObject ("WinMgmts:Root\Cimv2")
Set colProcess = objSWbemServices.ExecQuery _
("Select * From Win32_Process where name = 'wscript.exe'")
For Each objProcess In colProcess
WScript.Echo objProcess.Name, _
objProcess.ProcessId, _
objProcess.CommandLine
Next
I made a script and at the beginning i wanted to avoid having multiple / duplicate instances of the same process running. This is my code to quit the newer instance in case it gets launched when already running.
Note: This does note prevent multiple wscripts files from running - just prevents the same particular file from having simultaneous instances.
To adapt to suit the original question... just use the block which checks current running processes, if the any of the wscript file names equal the script file you're looking for, then it's running.
function duplicate_check
'if two scripts get here at the same time - stagger when the generate _
'the list of running processes _
'ie - give 1 of them time to close
'else they can both quit leaving no more scripts running
call random_script_sleep(2500,500)
dim myfilename
myfilename = Wscript.ScriptName
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("select * from win32_process")
'fill arrary w/ all running script names
i = 0
For Each objProcess in colProcesses
If objProcess.Name = "wscript.exe" Then
strScriptName = Trim(Right(objProcess.CommandLine,Len(objProcess.CommandLine) - InstrRev(objProcess.CommandLine,"\")))
strScriptName = Left(strScriptName, Len(strScriptName) - 1)
a(i)= strScriptName '
i=i+1
end if
Next
'kill script if already running w/ same name
if i > 1 then 'if > 1 wscript instance
for s = 0 to i
if a(s) = myfilename then
wscript.quit
end if
next
end if
'sometimes duplicate check fails, if so, write to error log
If Err.Number = 1 Then
error_notes = " #duplicate check, firstdupcheck(0/1):" & firstdupcheck
call error_log
error_notes = "error undefined"
end if
' if debugmsg = 1 then CreateObject("WScript.Shell").Popup _
' "found this many scripts: " & i & vbCrlf & _
' "<>" & i & vbCrlf & _
' ", 1, "debug popup"
end function
#nimizen answer is not correct. If you have another wscript running, it will return that your script is already running.
#h pic answer is correct, but I get an error with the "a" array in my windows. So I changed it a little and cleaned to work.
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("select * from win32_process where name = 'wscript.exe'")
i = 0
For Each objProcess in colProcesses
if not (IsNull(objProcess.CommandLine )) then
strScriptName = Trim(Right(objProcess.CommandLine,Len(objProcess.CommandLine) - InstrRev(objProcess.CommandLine,"\")))
strScriptName = Left(strScriptName, Len(strScriptName) - 1)
if strScriptName = Wscript.ScriptName then
i=i+1
end if
if i > 1 then 'if > 1 wscript instance
'Wscript.Echo "Duplicate :"&strScriptName&" ."
Wscript.Quit
end if
end if
Next
'Wscript.Echo "Pause 2 have 2 scripts running ."
Hmm, well first if its an infinite loop script, then you're probably using it to periodically check a folder to do some work. This sounds bad but is usually less resource intense than hooking into WMI for notifications. If its up and running, its running. The real problem is discriminating it from all the other WScript and CScripts scripts you may have running.
MS Sysinternals Process Explorer http://technet.microsoft.com/en-us/sysinternals/bb896653 is good at telling you information about your running processes. Mostly I would use it to tell by unique command line arguments which script process is hosting which script.
There is no easy way to exactly find your script's process Id from within a script. It is one of the few pieces of runtime information not exposed in the script environment's object model. Since you are already using the File System Object perhaps you could have it look for a dummy file name to use as the indicator that it is running. If the script couldn't create or open the file then you could assume that another instance of the script is already running.
Or have another unique named dummy file that you can easily create and your script automatically deletes during its processing run. That way you simply create an empty file of that name as a test and if it doesn't disappear in a few seconds you know no instances of your script are running.
Also I was thinking that you could launch your script from another script using Exec() which returns the ProcessID of the launched script and then release your reference to it, storing the ProcessID wherever you need it for later use.
Set oExec = WshShell.Exec( "infinite.vbs" )
MyProcessID = oExec.ProcessID ' procID of shell'd program.
set oExec = Nothing
and do something with MyProcessID
Then I noticed this posting
Find my own process ID in VBScript
Which uses Exec() to run an HTA script, get its ProcessID and look that up in WMI, then use the result set from WMI to locate the Parent process' ProcessID which should be the script making the Exec() and WMI calls. The problem with it is the HTA may terminate before WMI gets a chance to find it.
Dim iMyPID : iMyPID = GetObject("winmgmts:root\cimv2").Get("Win32_Process.Handle='" & CreateObject("WScript.Shell").Exec("mshta.exe").ProcessID & "'").ParentProcessId
Mostly I get the feeling that this is all overkill for whatever reason you think you need to know if the script is running. Instead focus on what action "knowing if the process is running or not" causes you to take. Since that hasn't been explained we really can't offer you an alternative strategy to get you there, but I'm sure a more simple solution is available. TheFolderSpy http://venussoftcorporation.blogspot.com/2010/05/thefolderspy.html for example would be one alternative way to run your program without an infinite loop.
Don't forget to use a sleep command in your loop to let other programs get work done. It makes a great difference in resource use. Also you only need one FSO instance, make it global to all your code by creating it early on in your script before any subroutines.
Since you are looking at the size of a file, you are probably checking it for changes. I've found that a loop with a small WScript.Sleep 200 delay in it is good to detect if a file is done being altered. That way you can process the file instead of having to skip it until the next main loop pass which should be set to 10 seconds or more.