locked
Powershell get-wmiobject takes very long time on remote machine RRS feed

  • Question

  • I am trying to create simple script to make manipulate disk quota so my life will be easier:)

    Here is my code (please be gentle)

    [CmdletBinding()]

    Param(

      [Parameter(Mandatory=$True)]
      [string]$USER,

      [Parameter(Mandatory=$True)]
      [int]$Amount_TEMP,

      [Parameter(Mandatory=$True)]
      [string]$Drive,

      [Parameter(Mandatory=$True)]
      [string]$SERV

      )
    $Drive = "$Drive" + ":"
    $USER = "$USER" + '"'
    $Amount = $Amount_TEMP * 1GB
    $WARNING = $Amount - 100MB
    Invoke-Command -ComputerName $SERV -ScriptBlock {
    $VALUE = get-wmiobject -class "Win32_DiskQuota" -namespace "root\CIMV2" | Where-Object {($_.User -like "*$USER") -and ($_.QuotaVolume -like "*$Drive*")}

    $VALUE.Limit = $Amount
    $VALUE.WarningLimit = $WARNING
    $VALUE.Put()}

    I know that such approach will work locally (tested and by using Put method I could write edited Variable value into WMI. However I am unable to even test that on remote due to script hanging. Could you please advise how to make it work?

    Thursday, September 14, 2017 11:26 AM

Answers

  • Get-WmiObject does not use WsMan.  It uses DCOM.  Your analysis is not correct.

    THe timeout is controlled by the client and not by the server.


    \_(ツ)_/

    Friday, September 15, 2017 9:28 AM

All replies

  • There is no need to use Invoke-Command with Get-WmiObject. If you read the help on Get-WmiObject, you'll see there is a parameter called ComputerName

    If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful. (99,108,97,121,109,97,110,50,64,110,121,99,97,112,46,114,114,46,99,111,109|%{[char]$_})-join''

    Thursday, September 14, 2017 12:16 PM
  • Yes I know I can simply replace Invoke-Command with -Computername in part:

    $VALUE = get-wmiobject -class "Win32_DiskQuota" -namespace "root\CIMV2" | Where-Object {($_.User -like "*$USER") -and ($_.QuotaVolume -like "*$Drive*")}

    But what will happen to second part:

    $VALUE.Put()

    Would't that force system to try to add that setting to local server instead of remote?


    Thursday, September 14, 2017 12:36 PM
  • I think you are correct on the last part, I've never used it before so not 100% sure.

    If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful. (99,108,97,121,109,97,110,50,64,110,121,99,97,112,46,114,114,46,99,111,109|%{[char]$_})-join''

    Thursday, September 14, 2017 1:27 PM
  • You do not need Invoke and the command will work remotely.  That is what the "ComputerName" argument does.

    Also drop all of the annoying quotes.

    $quota = get-wmiobject Win32_DiskQuota -Filter "User = '$USER' AND QuotaVolume = '$Drive'" -ComputerName $ComputerName


    \_(ツ)_/


    • Edited by jrv Thursday, September 14, 2017 3:19 PM
    Thursday, September 14, 2017 2:53 PM
  • You do not need Invoke and the command will work remotely.  That is what the "ComputerName" argument does.

    Also drop all of the annoying quotes.

    $quota = get-wmiobject Win32_DiskQuota -Filter "User = '$USER' QuotaVolume = '$Drive'" -ComputerName $ComputerName


    \_(ツ)_/

    After calling Get-WMIObject, user is then setting some settings and using the Put() function, will this still go against the remote machine if using the ComputerName parameter, or will that execute on the machine where the script runs?

    I've never used that method before, so unsure.


    If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful. (99,108,97,121,109,97,110,50,64,110,121,99,97,112,46,114,114,46,99,111,109|%{[char]$_})-join''

    Thursday, September 14, 2017 2:59 PM
  • Absolutely.  Why wouldn't it.  That is what WMI is for and how it works.

    \_(ツ)_/

    Thursday, September 14, 2017 3:05 PM
  • This code will not work:

    get-wmiobject Win32_DiskQuota -Filter "User = '$USER' QuotaVolume = '$Drive'" -ComputerName $ComputerName

    Even:

    get-wmiobject -class "Win32_DiskQuota" -namespace "root\CIMV2" -Filter "User = '$USER' QuotaVolume = '$Drive'"

    Will not work (tested locally without -Computername parameter)

    get-wmiobject : Invalid query "select * from Win32_DiskQuota where User = 'X"'QuotaVolume = 'E:'"

    The issue is I can make it work with like that, but then how to load these values via Put into remote machine?

    Thursday, September 14, 2017 3:10 PM
  • This code will not work:

    get-wmiobject Win32_DiskQuota -Filter "User = '$USER' QuotaVolume = '$Drive'" -ComputerName $ComputerName

    Even:

    get-wmiobject -class "Win32_DiskQuota" -namespace "root\CIMV2" -Filter "User = '$USER' QuotaVolume = '$Drive'"

    Will not work (tested locally without -Computername parameter)

    get-wmiobject : Invalid query "select * from Win32_DiskQuota where User = 'X"'QuotaVolume = 'E:'"

    The issue is I can make it work with like that, but then how to load these values via Put into remote machine?

    Sorry typo:

    $quota = get-wmiobject Win32_DiskQuota -Filter "User = '$USER' AND QuotaVolume = '$Drive'" -ComputerName$ComputerName


    \_(ツ)_/


    • Edited by jrv Thursday, September 14, 2017 3:19 PM
    Thursday, September 14, 2017 3:19 PM
  • That:

    $quota = get-wmiobject Win32_DiskQuota -Filter "User = '$USER' AND QuotaVolume = '$Drive'" -ComputerName$ComputerName

    Will simply not work, let me show you why. This is output from unfiltered command:

    DiskSpaceUsed       Limit QuotaVolume                     User                                                 
    -------------       ----- -----------                     ----                                                 
                0           0 Win32_LogicalDisk.DeviceID="C:" Win32_Account.Domain="My server name",Name="Administrators"

    Formatting is off, but you should get the idea: User property is not simply JOHN DOE, it is 

    Win32_Account.Domain="My server name",Name="John Doe"

    This is why I can't filter it easily (granted that would be waaay more efficient)

    Thursday, September 14, 2017 3:28 PM
  • Then you will have to use a more complex query that can filter on the related account.  

    Add this into the Filter.

    User='Win32_Account.Domain=""fabrikam"",Name=""kenmyer""'


    \_(ツ)_/

    Thursday, September 14, 2017 3:32 PM
  • Still get 

    get-wmiobject : Invalid query "select * from Win32_DiskQuota where User=Win32_Account.Domain="MYDOMAIN",Name=""Account I know is there"""

    Tried just 1 line of code:

    get-wmiobject -class "Win32_DiskQuota" -namespace "root\CIMV2" -Filter User='Win32_Account.Domain=""MYDOMAIN"",Name=""Account I know is there""'

    However I managed to run:

    $quota = get-wmiobject -class "Win32_DiskQuota" -namespace "root\CIMV2" -ComputerName Myserver | Where-Object {($_.User -like "*Account I know is there*") -and ($_.QuotaVolume -like "*E:*")}

    $quota

    And got data required

    (cheap test version of my script to test concept)

    So I added

    $quota.Limit=2147483648
    $quota.Put()

    Ran for like 30 minutes, then gave me:

    Exception calling "Put" with "0" argument(s): "Invalid parameter "
    At line:4 char:1
    + $quota.Put()

    So I presume that Put() will not work without Invoke...

    Thursday, September 14, 2017 3:58 PM
  • If the account exceeds the requested limit or if the disk has errors you may get this.  I suggest testing the target system for issues.

    It is running for a long time because you are setting a limit which requires a complete file system scan to do the initial quota calculation.  On a large disk this can take a long time.  On a bad disk or with a corrupted file system this can fail.


    \_(ツ)_/

    Thursday, September 14, 2017 4:05 PM
  • Tested on few servers, and actually checked the log.

    Error message: Sending data to a remote command failed with the following error message: The WS-Management service cannot complete the operation within the time specified in OperationTimeout. 

    I could increase timeout to let's say 5 mins according to article here:

    https://support.f5.com/csp/article/K14062

    But I just lost heart to whole thing... It will take less than 5 mins to log into server in question and change that settings manually. So much for remote WMI promises

    I know that WSMAN must pass objects, but performance is atrocious.

    Thank you all for the help - I really appreciate that:)
    • Edited by Wojciech_Rodzik Friday, September 15, 2017 9:25 AM Wanted to say thanks
    Friday, September 15, 2017 9:25 AM
  • Get-WmiObject does not use WsMan.  It uses DCOM.  Your analysis is not correct.

    THe timeout is controlled by the client and not by the server.


    \_(ツ)_/

    Friday, September 15, 2017 9:28 AM
  • Get-WmiObject does not use WsMan.  It uses DCOM.  Your analysis is not correct.

    THe timeout is controlled by the client and not by the server.


    \_(ツ)_/

    Mhm this is interesting....

    In theory time required for system to run

    invoke-command servername -script {get-wmiobject something}

    Would be different than

    get-wmiobject something -computername servername

    I will test both cases on some less demanding class just for fun

    Tested: there is visible difference in time. Invoke-command takes way less time to complete (tested on  Win_32_DeviceBus)

    Friday, September 15, 2017 10:46 AM
  • Hi,

    I'm checking how the issue is going, was your issue resolved?

    And if the replies as above are helpful, we would appreciate you to mark them as answers, and if you resolve it using your own solution, please share your experience and solution here. It will be greatly helpful to others who have the same question.

    Appreciate for your feedback.

    Best Regards,
    Albert Ling

    Please remember to mark the replies as an answers if they help and unmark them if they provide no help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com.

    Thursday, September 21, 2017 11:18 AM