PowerCLI

 View Only
  • 1.  PowerCLI script runs fine normally, fails when called by apcupsd (linux)

    Posted Feb 02, 2022 04:06 AM

    So I've written a PowerCLI script to use with apcupsd to shutdown any VMs running on NAS datastores and shut them down first (so the NAS can then shut down).

    Here's a cut down version of the script - ignore the variables that aren't initialised, gets pulled from a file and works fine but clutters things up so I took it out. When I run this from the command line, it works perfectly. Does exactly what I want it to do.

     

    #!/usr/bin/powershell/pwsh
    
    Write-Output "PS Environment Variables: "
    Write-Output $Env:PSModulePath
    
    $server = $($item.SERVER)
    $user = $($item.USER)
    $pass = ConvertTo-SecureString $($item.PASSWORD) -AsPlainText -Force
    
    # Create credential object
    $pscreds = New-Object System.Management.Automation.PSCredential ($user, $pass)
    
    # Connect to server
    Connect-VIServer $server -Credential $pscreds
    
    # Find any datastore with NAS as part of the name, grab any running VM's and issue a guest shutdown
    Get-Datastore | Where{$_.name -like '*NAS*'} | Get-VM | Where{$_.PowerState -eq 'PoweredOn'} | Shutdown-VMGuest -Confirm:$false

     

     

    But when I then add it to the APCUPSD config it gets called when it's supposed to.. and fails with the following output:

     

    PS Environment Variables:
    /tmp/9d12ecbf-5362-4faa-98a3-d45f001a03c5/.local/share/powershell/Modules:/usr/local/share/powershell/Modules:/usr/bin/powershell/Modules
    
        Directory: /usr/bin/powershell/Modules
    
    ModuleType Version    PreRelease Name                                PSEdition
    ---------- -------    ---------- ----                                ---------
    Script     12.5.0.19…            VMware.CloudServices                Desk
    <snip - lists all modules>
    Script     12.1.0.16…            VMware.VumAutomation                Desk
    
    Connect-VIServer: /root/scripts/VMShutDown/test.ps1:16
    Line |
      16 |      Connect-VIServer $server -Credential $pscreds
         |      ~~~~~~~~~~~~~~~~
         | The 'Connect-VIServer' command was found in the module
         | 'VMware.VimAutomation.Core', but the module could not be
         | loaded. For more information, run 'Import-Module
         | VMware.VimAutomation.Core'.
    
    Get-Datastore: /root/scripts/VMShutDown/test.ps1:19
    Line |
      19 |      Get-Datastore | Where{$_.name -like '*NAS*'} | Get-VM | Where{$_. …
         |      ~~~~~~~~~~~~~
         | The type initializer for
         | 'VMware.VimAutomation.Sdk.Interop.V1.CoreServiceFactory' threw
         | an exception.

     

     

    No difference other than it's being run by apcupsd so my thought was some kind of environment variable missing, but I specifically installed the module into the /usr/bin/powershell/Modules directory with the following, and it works just fine when called via the command line

     

    Find-Module -Name 'VMware.PowerCLI' -Repository 'PSGallery' | Save-Module -Path /usr/bin/powershell/Modules
    Import-Module -FullyQualifiedName '/usr/bin/powershell/Modules/VMware.PowerCLI'

     

     

    So pretty stumped. Any ideas welcome.



  • 2.  RE: PowerCLI script runs fine normally, fails when called by apcupsd (linux)

    Posted Feb 02, 2022 07:27 AM

    Why do you hae the /tmp folder in the PSModulePath variable?
    I would suggest to remove all PowerCLI related directories in all folders mentioned in PSModuePath.
    Then do a fresh install with Install-Module.

    Not sure why you are doing the Save-Module part?
    That should only be required when installing on a station that has no connection to the PSGallery.



  • 3.  RE: PowerCLI script runs fine normally, fails when called by apcupsd (linux)

    Posted Feb 02, 2022 10:02 AM

     wrote:

    Why do you hae the /tmp folder in the PSModulePath variable?

    That's something that only shows up when the script is called by the system, presumably it creates its own temporary space for that session in case it's needed.

    The path when run as root is:

    PS /root> Write-Output $Env:PSModulePath
    /root/.local/share/powershell/Modules:/usr/local/share/powershell/Modules:/usr/bin/powershell/Modules

     


     wrote:

    Not sure why you are doing the Save-Module part?
    That should only be required when installing on a station that has no connection to the PSGallery.


    Initially the modules were being installed in /root/.local/share/powershell/Modules and only available to root when run from the command line (or whatever other user installed the module). When run by the system even as root the same environment variable isn't used.

    Pulling the module down with Save-Module then forcing it to install to /usr/bin/powershell/Modules made it available. Prior to this I installed it as per normal with just Install-Module however the PowerCLI commands were not available at all.


     wrote:

    I would suggest to remove all PowerCLI related directories in all folders mentioned in PSModuePath.
    Then do a fresh install with Install-Module.


    Yep was how I initially had it but the module was not available to the system, hence the Save-Module. I've tried multiple fresh installs - they all work just fine when running the script directly or using the commands from a session, but they won't work when called by the system.



  • 4.  RE: PowerCLI script runs fine normally, fails when called by apcupsd (linux)

    Posted Feb 02, 2022 01:22 PM

    If Install-Module installs in a User directory, that means the Scope is the default, namely CurrentUser.
    When you do with the Scope AllUsers, it should be in a folder accessible to all users.



  • 5.  RE: PowerCLI script runs fine normally, fails when called by apcupsd (linux)

    Posted Feb 02, 2022 10:00 PM

     wrote:

    If Install-Module installs in a User directory, that means the Scope is the default, namely CurrentUser.
    When you do with the Scope AllUsers, it should be in a folder accessible to all users.


    That was one of the first things I tried to resolve the modules not being accessible, but I can't recall if I did it with a fresh powershell install or not. Will give that a try.



  • 6.  RE: PowerCLI script runs fine normally, fails when called by apcupsd (linux)

    Posted Feb 02, 2022 10:13 PM

    Make sure to first remove the installation in all user directories.
    Unfortunately Install-Module allows you to install in both scopes, without even requiring a confirmation.



  • 7.  RE: PowerCLI script runs fine normally, fails when called by apcupsd (linux)

    Posted Feb 02, 2022 11:47 PM

    Still no luck. Completely removed Powershell then went through the PS Environment variables and checked every single directory to make sure there was nothing there, did a new install, then added the module with:

    Install-Module -Name 'VMware.PowerCLI' -Scope AllUsers

     

    Installed just fine, this time to /usr/local/share/powershell/Modules which the log of the script shows is where the module is being pulled from. But still getting the same result:

     

    PS Environment Variables:
    /tmp/cd37f0ff-da59-43ac-84e1-c8e2c8e4b78b/.local/share/powershell/Modules:/usr/local/share/powershell/Modules:/usr/bin/powershell/Modules
    
        Directory: /usr/local/share/powershell/Modules
    
    ModuleType Version    PreRelease Name                                PSEdition
    ---------- -------    ---------- ----                                ---------
    Script     12.5.0.19…            VMware.CloudServices                Desk
    etc.
    
    Connect-VIServer: /root/scripts/VMShutDown/test.ps1:16
    Line |
      16 |      Connect-VIServer $server -Credential $pscreds
         |      ~~~~~~~~~~~~~~~~
         | The 'Connect-VIServer' command was found in the module
         | 'VMware.VimAutomation.Core', but the module could not be
         | loaded. For more information, run 'Import-Module
         | VMware.VimAutomation.Core'.

     

    Only thing I can think of is to redeploy the server entirely but somewhat at a loss as to what that would achieve given powershell is just an extracted directory.



  • 8.  RE: PowerCLI script runs fine normally, fails when called by apcupsd (linux)
    Best Answer

    Posted Feb 03, 2022 04:38 AM

    OK... solved it!

    Started just printing everything I could for debugging and saw there was no HOME var (linux var, not powershell). Apparently if PowerCLI doesn't have a HOME environment variable set, it won't work no matter where you put the modules. Added the following to the script that calls the ps1, problem solved (obviously if using a different service account would need to change accordingly).

     

     

     

    export HOME=/root

     

     

     

    I assume it's due to PowerCli storing its settings in ~/.local/share/VMware/PowerCLI  and not able to pick them up without a HOME var.

     

    Edit: just a suggestion if anyone wants it, but if practical I'd very much recommend moving to a "check if config exists in ~ if not use the default from /etc" or similar way of doing things.