VBA – Run PowerShell Command

Windows PowerShell

Have you ever wanted to run a PowerShell command from within VBA and get back a value?

Executing a PowerShell Command From VBA

Before getting into returning a response, let first look at simply executing a command. There are many instances in which we simply want to run a PowerShell command and don’t need to get any response back.

It turns out that it is very easy to do and very similar to the approach taken in VBA – Get Host IP Address.

PowerShell can simply be called/executed from a standard command prompt using the command

powershell -command

Armed with this information when can simple use a WScript Shell object to execute the command, thus giving us a simple function along the lines of

'---------------------------------------------------------------------------------------
' Procedure : PS_Execute
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Run a PowerShell command
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding  -> none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPSCmd : PowerShell command to run
'
' Usage:
' ~~~~~~
' Copy a File
'   PS_Execute "Copy-Item -Path C:\temp\Book1.xls -Destination C:\temp\charts\Book1.xls -Force"
' Create a Directory or Directories
'   PS_Execute "New-Item -Path 'C:\temp\charts\Test' -ItemType Directory"
'   Can do multiple directories in one call!
'   PS_Execute "New-Item -Path 'C:\temp\charts\Test\1\2\3\4' -ItemType Directory"
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2020-04-13              Initial Release
'---------------------------------------------------------------------------------------
Public Sub PS_Execute(ByVal sPSCmd As String)
    'Setup the powershell command properly
    sPSCmd = "powershell -command " & sPSCmd
    'Execute and capture the returned value
    CreateObject("WScript.Shell").Exec (sPSCmd)
End Sub

The issue with the above is that it generates a visible PowerShell window that the end-user will see. Luckily, there a a small change we can make to avoid this. By switching from using .Exec to .Run we can silently run PowerShell commands. As such, our procedure becomes

'---------------------------------------------------------------------------------------
' Procedure : PS_Execute
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Run a PowerShell command
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding  -> none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPSCmd : PowerShell command to run
'
' Usage:
' ~~~~~~
' Copy a File
'   PS_Execute "Copy-Item -Path C:\temp\Book1.xls -Destination C:\temp\charts\Book1.xls -Force"
' Create a Directory or Directories
'   PS_Execute "New-Item -Path 'C:\temp\charts\Test' -ItemType Directory"
'   Can do multiple directories in one call!
'   PS_Execute "New-Item -Path 'C:\temp\charts\Test\1\2\3\4' -ItemType Directory"
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2020-04-13              Initial Release
' 2         2024-02-07              Added quotes around command string
'                                   Added ExecutionPolicy, bShowShell, bDebug arguments
'---------------------------------------------------------------------------------------
Public Sub PS_Execute(ByVal sPSCmd As String, _
                      Optional sExecutionPolicy As String, _
                      Optional bShowShell As Boolean = False, _
                      Optional bDebug As Boolean = False)
    'Setup the powershell command properly
    If sExecutionPolicy = "" Then
        sPSCmd = "powershell -command """ & sPSCmd & """"
    Else
        sPSCmd = "powershell -executionpolicy " & sExecutionPolicy & " -command """ & sPSCmd & """"    'Required to make BurntToast work
    End If
    If bDebug Then Debug.Print sPSCmd
    'Execute the command
    If bShowShell Then
        CreateObject("WScript.Shell").Run sPSCmd, 1, True    'Display to user
    Else
        CreateObject("WScript.Shell").Run sPSCmd, 0, True    'Hide from user
    End If
End Sub

Now that we know the basics, let’s look at how we could then return the response from PowerShell commands.

Returning a PowerShell Value in VBA

The next step is to return the response in the case where one is generated. Luckily for us the WScript Shell object provides us with everything we need with the StdOut (standard output) property and ReadAll Method.

'---------------------------------------------------------------------------------------
' Procedure : PS_GetOutput
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Run a PowerShell command and return the response
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding  -> none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPSCmd : PowerShell command to run and return the value/response of
'
' Usage:
' ~~~~~~
' ? PS_GetOutput("Get-ComputerInfo -Property 'OsName'")
'   Returns
'       OsName
'       ------
'       Microsoft Windows 10 Home
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2020-04-13              Initial Release
'---------------------------------------------------------------------------------------
Public Function PS_GetOutput(ByVal sPSCmd As String) As String
    'Setup the powershell command properly
    sPSCmd = "powershell -command " & sPSCmd
    'Execute and capture the returned value
    PS_GetOutput = CreateObject("WScript.Shell").Exec(sPSCmd).StdOut.ReadAll
End Function

Now the problem with the above is that is opens the PowerShell prompt and makes it visible to the user while the command is executed. So this is less than ideal.

Silently Retrieving the PowerShell Response

One approach to retrieving the PowerShell response is to simply output the command response to a Text file.

Originally, I tried doing so by appending the PowerShell command, like we do in DOS …

sPSCmd = "powershell -command " & sPSCmd & ">" & sFile

To my surprise the text file, when read back into memory, was a mess.

ÿþ
 
 O s N a m e                                       
 
 - - - - - -                                       
 
 M i c r o s o f t   W i n d o w s   1 0   H o m e 

It would appear that it defaulted to Unicode format. Luckily for me, PowerShell offers another way to export a file and specific the format to use. So I was able to tweak the code to get a standard ASCII text file and I was back in business. The end result was

'---------------------------------------------------------------------------------------
' Procedure : PS_GetOutput
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Run a PowerShell command and return the response
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding  -> none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPSCmd        : PowerShell command to run and return the value/response of
' sTxtFile      : Text file to output the response to and then read from
' bDelTxtFile   : Whether to delete the generated text file or not
'
' Usage:
' ~~~~~~
'?PS_GetOutput("Get-ComputerInfo -Property 'OsName'", _
'               Environ("userprofile") & "\Desktop\PSTest.txt", False)
'?PS_GetOutput("Get-ComputerInfo -Property 'OsName'")
'   Returns
'       OsName
'       ------
'       Microsoft Windows 10 Home
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2020-04-13              Initial Release
'---------------------------------------------------------------------------------------
Public Function PS_GetOutput(ByVal sPSCmd As String, _
                              Optional sTxtFile As String = "", _
                              Optional bDelTxtFile As Boolean = True) As String
    'If no Text file was specified create one in the Temp folder
    If sTxtFile = "" Then sTxtFile = Environ("temp") & "\PSTemp.txt"
    'Build the basic PowerShell command
    sPSCmd = "powershell -command " & sPSCmd
    'Add the Out-File so the output generates a text file
    sPSCmd = sPSCmd & " | Out-File '" & sTxtFile & "' -encoding ASCII"
    'Run the PowerShell command
    CreateObject("WScript.Shell").Run sPSCmd, 0, True
    'Retrieve the content of the generated Text file
    With CreateObject("Scripting.FileSystemObject")
        'Read the contents of the text file into memory
        PS_GetOutput = .OpenTextFile(sTxtFile).ReadAll()
        'Delete the text file if so desired
        If bDelTxtFile = True Then .DeleteFile sTxtFile
    End With
End Function

Perfecting the Function

Now the above is just fine, but it does uselessly use I/O by constantly reading/writing to the harddrive. So I though I’d present another option that the WScript Shell object offers us, which is to push the result to the clipboard. So, below is an example in which the WScript Shell object executes the PowerShell command silently (not shown to the user) and saves the result to the clipboard where we can then easily retrieve it.

'---------------------------------------------------------------------------------------
' Procedure : PS_GetOutput
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Run a PowerShell command and return the response
'               Improved version where the PS prompt is never displayed to the user
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding  -> none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPSCmd : PowerShell command to run and return the value/response of
'
' Usage:
' ~~~~~~
' ? PS_GetOutput("Get-ComputerInfo -Property 'OsName'")
'   Returns
'       OsName
'       ------
'       Microsoft Windows 10 Home
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2020-11-05              Initial Release
'---------------------------------------------------------------------------------------
Public Function PS_GetOutput(ByVal sPSCmd As String) As String
    'Setup the powershell command properly
    sPSCmd = "powershell -command " & sPSCmd & "|clip"
    'Execute the command which is being pushed to  the clipboard
    CreateObject("WScript.Shell").Run sPSCmd, 0, True
    'Get an instance of the clipboard to capture the save value
    With CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
        .GetFromClipboard
        PS_GetOutput = .GetText(1)
    End With
End Function

So there you go, in a few lines of code we can have the full power of PowerShell available to us without needing to read and write to the hard drive.

What About Elevated Priviledges – Run As

Executing a Command with Elevated Priviledges

One thing I’ve noticed playing around with PowerShell on my PC to develop the information herein is the fact that many commands seem to need to be Run As administrator to work even though performing the same action manually does not. Example of this would be turning off my WiFi, Disabling my print Spooler; I can do this in a few click without UAC, yet through PowerShell I have to use Run As.

Long story short, I wanted to find a way to do the same in VBA, it took a little playing around to get the syntax just right ” and ‘ at the right places, but the end result is

Public Sub PS_Admin_Execute(ByVal sPSCmd As String)
'Setup the powershell command properly
    sPSCmd = "powershell -command ""Start-Process powershell -Verb runAs " & _
             "-ArgumentList '-Command " & sPSCmd & "'"""
    'Execute and capture the returned value
    CreateObject("WScript.Shell").Run sPSCmd, 0, True
End Sub

So the trick is to launch an instance of PowerShell and tell it to launch another instance with elevated proviledges and run your command.

Now the above does indeed work, but there is one little problem. Although the WScript Run window is hidden, the secondary PowerShell windows is not. Once again, thanks to the power of PowerShell there is actually an easy fix, we add the -WindowStyle argument when creating the 2nd instance. So the procedure simply becomes

Public Sub PS_Admin_Execute(ByVal sPSCmd As String)
'Setup the powershell command properly
    sPSCmd = "powershell -command ""Start-Process powershell -Verb runAs -WindowStyle Hidden " & _
             "-ArgumentList '-Command " & sPSCmd & "'"""
    'Execute and capture the returned value
    CreateObject("WScript.Shell").Run sPSCmd, 0, True
End Sub

Then, with the above, you can then simply do, for instance:

Stop/Start the Print Spooler

PS_Admin_Execute "Stop-Service -Name spooler"
PS_Admin_Execute "Start-Service -Name spooler"

Disable/Enable the WiFi Adapter

PS_Admin_Execute "get-netadapter wi-fi |disable-netadapter -confirm:$false"
PS_Admin_Execute "get-netadapter wi-fi |enable-netadapter"

Getting the Output of a Command Run with Elevated Priviledges

Similarily to the other case, we can use the clipboard with the runAs Verb argument. As such we would end up with something like

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Function PS_Admin_GetOutput(ByVal sPSCmd As String) As String
Dim i As Long

'Setup the powershell command properly
    sPSCmd = "powershell -command ""Start-Process powershell -Verb runAs -WindowStyle Hidden " & _
             "-ArgumentList '-Command " & sPSCmd & "|clip'"""
    'Execute and capture the returned value
    CreateObject("WScript.Shell").Run sPSCmd, 0, True
    With CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
        .GetFromClipboard
        'Wait for a value to appear in the clipboard, remember PowerShell is slow!
        On Error Resume Next
        For i = 0 To 100
            PS_Admin_GetOutput = .GetText(1)
            If Err.Number <> 0 Then
                Err.Clear
            Else
                Exit For
            End If
            Sleep 100 'Don't forget the API declaration!
        Next i
    End With
End Function

Do notice I’ve had to add a loop with a sleep/delay to wait for PowerShell instance to be created, run the command and return its response.

The above function can then be used by doing

Get the OS Name

? PS_Admin_GetOutput("Get-ComputerInfo -Property ""OsName""")

The UAC in All of This?!

The above works fine, but do note that you do get a UAC prompt that you have to authorize for the command to execute and I’ve found no way around this. It’s a security thing!

PowerShell UAC Prompt

Because of this issue, the UAC prompt, I’d advise against using this Run As approach universally. Use the original standard code for everything you can so your users don’t have to deal with any prompts, but if ever you truly need to use commands requiring elevated permission, the code is here for you to use.

A Few Last Words On The Subject

As you can see by the code, these functions are completely application non-specific and can be used in any application that has VBA (Access, Excel, Outlook, PowerPoint, Word, …) making them that much more useful to us.

One general comment, PowerShell is slow, powerfull, but slow. As such, running PowerShell commands can cause delays when compared to other functions. So think carefully to ensure there are better alternatives. That said, PowerShell opens a whole new world of possibilities to extend beyond what we can do via VBA normally!

Also, be sure to add some error handling! What I’ve presented above works just fine, but is still bare bones and you should add proper error handling to ensure no nasty surprises for your end-users.

If you wish to do more reading regarding the Windows Shell then refer to https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/windows-scripting/98591fh7(v=vs.84)

Also, I wanted to point out is that if you use the .Exec method (that is shown to the user), you can wait for the command to run and check the returned status to know if the command Finished or Failed, but it doesn’t seem to be possible to do the same thing using the .Run method?! So if you are interested in going down to this level of coding, it is possible, but you must use .Exec, check the Status property and then return the StdErr property using the ReadAll method.

Lastly, my procedures solely use the powershell command-line parameter ‘-Command‘ to make it the most versatile possible, but do note that there are many more that can be employed depending on what you are doing, most notably ‘-NoProfile‘, ‘-NonInteractive‘, ‘-OutputFormat‘, ‘-ExecutionPolicy‘. For a full listing be sure to review: about_PowerShell_exe.

I truly hope this will help a few of you out there. It was fun to explore this subject a little bit.

37 responses on “VBA – Run PowerShell Command

  1. John Powell

    Very nice write-up, thank you for sharing. It was plug and play for me in my project. You saved me serious time trying to figure this all out on my own.

  2. Wesley

    Thank you. My access database has a menu form which contains a few ‘useful link’ buttons. I tried using Followhyperlink to Access my organization’s sharepoint (intranet) and got error 8 (unable to download file or whatever that translates to in English)

    I tried different solutions and powershell was one of them. I remembered you posted this code so I was happy to use it!

  3. Jack Stockton

    These can be helpful:
    PS_Admin_Execute “net start MSSQLSERVER”
    PS_Admin_Execute “net stop MSSQLSERVER”

  4. Steve Halder

    As always, your post is well researched, explained and very useful. Thank you so much for taking the time to do this!

  5. John F Clark

    I am simply repeating what others have said, but this Wrapper Function/Procedure is a real game changer. Thanks so much for taking the time to post this.

  6. Evan Hadjimarkos

    Probably the best organized notes I have seen anywhere. Everything is well documented and undestood.
    The only thing is that it did not work for me. What I’m trying to do is:
    a) get the drive letter of a locked USB with bitlocker
    b) and unlock it.
    c) Copy some files inside
    d) and lock it back.
    The command I’m using is manage-bde -unlock Z: -recoverypassword 240536-642752-211409-491690-520026-693407-016863-529159. On a powershell console runs fine. It doesn’t give an error and the widnows appear for allowing this app to make changes…. I click Yes and the code runs but the USB drive is still locked.
    I’m using VBA on MS-Access 2019 and a Windows 10 machine.

  7. Bruce Hulsey

    This is a good and helpful article, thanks for posting it. My only (small) concern is that all of the examples containing the comment “Execute and capture the returned value” don’t appear to actually “capture” any return value, unless I’m missing something. This might be a little confusing for beginners such as myself.

    1. Daniel Pineault Post author

      Bruce,

      You have 2 basic commands at the end of the day: PS_Execute & PS_GetOutput, if you want to return the output be sure to use PS_GetOutput.

      For instance, in the immediate window, try:

      ? PS_GetOutput("$env:temp")

      you should get back the path to your Temp folder

      Or try

      ? PS_GetOutput("Get-ChildItem Env:  | Sort Name, Value")

      which will return all your environment variables.

      Or, here’s another example, try:

      ? PS_GetOutput("Get-CimInstance Win32_OperatingSystem | Select @{n='OS'; e={$_.Caption + ' ' + $_.OsArchitecture + ' ' + $_.Version}} | FT -HideTableHeaders")

      which will return information about your OS.

      Also, some commands fail in normal PS command prompts and this is when you need elevated priviledges, so you need to then turn towards using: PS_Admin_Execute and PS_Admin_GetOutput. So if you are getting results using PS_GetOutput, perhaps try PS_Admin_GetOutput.

      I hope this helps.

  8. Johannes Lamers

    Hello,
    the idea to run the Powershell and putting the result to the clipboard is exactly what I want. I’ve been searching for three month to Run a command without popping Shell window. Her I found.
    Thank you very much
    Johannes Lamers

  9. Lorenzo Garuglieri

    Hello,
    is it possible to send messages to some computer on the company network (obviously knowing the comupter names) via PowerShell in MS ACCESS?

    Thank you

  10. Justin Howdy

    Daniel, awesome stuff.
    Thank you for explaining your scripts and showing your build up / thought process. I came across your site by way of the Image Exif Property extraction thread however it needed the PS_GetOutput function. There is an issue however, this is a company PC and any attempts of using PS result in malicious software detection and a machine lockdown. I can open PS from explorer.exe, so I believe I have limited rights. Do you know of any way around this or have a recommendation? My goal is to get the “Date Taken” from a photo.
    Respectfully,
    Justin

      1. Justin Howdy

        Excellent, thank you Daniel. I was able to solve the puzzle utilizing Shell. Application.
        Happy New Year,
        Justin

  11. Joe

    i read out the region setting on OS system works great, but the Euro sign is converted into a ?, tried other encodings but didn’t work. I need it to set the region settings to set to US and afther that setting them back to initial settings. (after doing some vba scripting that needs US region settings.
    any sugestions?

  12. Joe

    Thanks Daniel, I tried the “Special Characters and Internationalization of an Application” works for me, had to make some other changes, but I’ll get what I want .
    Maybe getting the values and put them in a csv/txt file in one call would be nice.

    1. Daniel Pineault Post author

      Not too hard to create, how about:

      '---------------------------------------------------------------------------------------
      ' Procedure : Regisrty_ExportInternationalSettings
      ' Author    : Daniel Pineault, CARDA Consultants Inc.
      ' Website   : http://www.cardaconsultants.com
      ' Purpose   : Enumerate all the International Setting Values and create a csv file on
      '               the user's desktop
      ' Copyright : The following is release as Attribution-ShareAlike 4.0 International
      '             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
      ' Req'd Refs: Late Binding  -> none required
      ' Dependencies: Txt_Append -> https://www.devhut.net/vba-append-text-to-a-text-file/
      '
      ' Usage:
      ' ~~~~~~
      ' Call Regisrty_ExportInternationalSettings
      '
      ' Revision History:
      ' Rev       Date(yyyy-mm-dd)        Description
      ' **************************************************************************************
      ' 1         2022-01-27              Blog Comment Request/Feedback
      '---------------------------------------------------------------------------------------
      Sub Regisrty_ExportInternationalSettings()
          On Error GoTo Error_Handler
          Dim oReg                  As Object
          Dim aNames                As Variant
          Dim sName                 As Variant
          Dim aTypes                As Variant
          Dim sValue                As String
          Dim sOutput               As String
          Const HKEY_CURRENT_USER = &H80000001
          Const sParentKey = "Control Panel\International"
      
          Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
          oReg.EnumValues HKEY_CURRENT_USER, sParentKey, aNames, aTypes    'Get all the Values within the sParentKey
          For Each sName In aNames    'Iterate through each Value
              oReg.GetStringValue HKEY_CURRENT_USER, sParentKey, sName, sValue
              sOutput = sOutput & Chr(34) & sName & Chr(34) & "," & Chr(34) & sValue & Chr(34) & vbCrLf
          Next
          If sOutput <> "" Then sOutput = Left(sOutput, Len(sOutput) - 2)
          Txt_Append Environ("USERPROFILE") & "\Desktop\InternationalSettings.csv", sOutput
      
      Error_Handler_Exit:
          On Error Resume Next
          If Not oReg Is Nothing Then Set oReg = Nothing
          Exit Sub
      
      Error_Handler:
          MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
                 "Error Number: " & Err.Number & vbCrLf & _
                 "Error Source: Regisrty_EnumerateKeyValues2" & vbCrLf & _
                 "Error Description: " & Err.Description & _
                 Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
                 , vbOKOnly + vbCritical, "An Error has Occured!"
          Resume Error_Handler_Exit
      End Sub

      As noted in the procedure header it requires a copy of Txt_Append

  13. Zar78

    Hello Daniel
    Your work is very interessant.
    How can I test your code with ‘Microsoft Visual Basic for Applications’.
    I copied your Functions in my environment, but I am not able to call them with a Sub macro.
    Can you help me? Can you show me an example?
    Thanks
    Consideration.
    Zar78

  14. Markus

    If you run WScript.Shell with the second parameter (intWindowStyle) = 0, the clipboard does eventually not copy all content – even if you use powershell commands like “Format-Table -Autosize”. This is because of the content within the hidden powershell window, which will perhaps be cut at the right side. (added “…” at the right side)
    To circumvent this, you have to use temporary files or start it with intWindowStyle = 3 (but this eventually also not helps if too much content is shown)

  15. John F Clark

    Daniel, I can use your wrapper function in VBScript and run the commands from both the Command Prompt and the from PowerShell directly. However, as soon as I try this from within Access, I get runtime error 70 – Permission Denied.

    I am assuming this is some sort of restriction imposed by my IT but figured I would ask. Any thoughts?

      1. John F Clark

        Thanks for the prompt reply. It used to work from Access with no issues. The funny this is, I can put your wrapper function is VBS and then “shell out” to my VBS – with parameters – just fine.
        Madness. Those Jerry’s Kids in our IT dept. aint seen the football since the kick-off…

  16. Mike Hamerly

    Hi Daniel, this powershell VBA script is exactly what I need. However when I copy your code and run as is, I get “System cannot find the file specified”. I am running 32 bit machine, latest excel and windows 11. Any ideas?

    1. Daniel Pineault Post author

      I don’t have Windows 11 so I really can’t comment. I am migrating to Linux, not interested in Windows as SASS.

      Your PS script works independently in the PowerShell ISE?

  17. Dave Talbot

    Hi Daniel
    Does VBA wait for the PS script to complete?
    I need to write a PS script to log a user off a Terminal Server after they have closed MS Access.
    My thought are to do the following:
    1. User clicks on ‘Close Database’ button in MS Access
    2. The close function calls a PS script which will pause for 5 seconds then log the user off the TS
    3. MS Access ‘Quits’ and the PS script completes its process after the wait period.

    Many thanks
    Dave Talbot (U)

  18. Leslie Desser

    Someone mentioned an issue that something that ran in a PS window did not produce any result when run using PS_Execute.

    I have had the same issue and it turns out that the command string while ok in the PS window generates syntax errors when submitted. I have tried it independently from the PS_Execute function so its not a PS_Execute issue.

    To see what is going on change the StdOut.ReadAll code to StdErr.ReadAll and you will get back the errors.

  19. Robert Simard

    Bonjour Daniel,
    En effectuant des recherches sur le Web, afin de pouvoir récupérer des valeurs par PowerShell, je suis tombé évidemment sur votre site Web 👍, vos fonctions fonctionnent très bien avec les commandes “Get-“, et elles me seront assurément d’une grande utilité!
    À l’aide de votre fonction, j’essaie de récupérer les utilisateurs actifs sur un serveur TS à l’aide de la commande : query user /server:myservername
    À votre avis, c’est possible avec vos fonctions ?
    Merci !

  20. Shivanand Baswannappa

    Thanks Daniel for the snippets,
    I incorporated them into our application which still runs on Access 2013/ – now 365.
    When I create zip file and rename them from power script functions in VBA, the screen flashes for a second!
    Is there a way to suppress it?
    Thanks

  21. Greg

    Daniel,

    This is awsome stuff! But I am having an issue when running the PS_Execute command from the immediate window in Access.
    I am getting a Compile Error Argument not optional error message.
    Here is what I am calling
    ?PS_Execute “Add-ADGroupMember -Identity ‘Sales’ -Members username”
    Any thoughts?

  22. Benedikt

    Hello Daniel!

    Thank you for thess great Examples! Exactly what I was looking for but unfortunately only runs partly for me. I would highly appriciate if you have any suggestion for me!
    I am facing this problem:
    I began with creating an Object like:
    Set shell = CreateObject(“WScript.Shell”)
    then some pices of code and finnally I got my string which I call s_command, it probably looks like this
    powershell.exe -WindowStyle hidden -command C:\myprogram.exe ‘Testfile 1.txt’ ‘C:\AWS\Testfile origin.txt’
    As you can see there are some arguments in my String which have spaces in them like the Filname ect.
    When I execute this command
    s_return = shell.Exec(s_command).StdOut.ReadAll()
    everything is working fine but the Poweshell window pops up for a second.

    When I do the same and send this command with your example code, which ever of those you posted it only works without spaces in my arguments. What I want to say is, my little program needs spaces as argument seperators and actually it has some more arguments which I hand over and I would really want to figure out the proper syntax to hand over arguments seperated from each other by spaces but inside arguments I would like to keep them.
    What is the diference between your example which is much better than mine because of not popping up, haveing elevated arguments possibility and only using the clipboard and mine wich is just haveing one benefit… I can use spaces in arguments.

    Sorry for my long post and many greetings!
    Benedikt

  23. Xevi

    Thanks Daniel. Great tool. Only I’d like to add that I save the Powershell output to a file in UTF-8 format to deal with internacional and extended ASCII characters.