none
Powershell - Easiest way to get output from different data structures RRS feed

  • Question

  • Hello, I have one list of objects

    [Collections.Generic.List[PSObject]]$computerArray = @()
    
    
    


    where I store some info about computers:

           $computerObject = [PSCustomObject][ordered]@{
    
                ComputerName        = $computerName
                ManagedBy           = $ManagedBy
                lastActivity        = $lastActivity
                Virtual             = $Virtual
                IPAddress           = $IPAddress
                VPN                 = $VPN
                Pinging             = $Pinging
                WinRMconnected      = $WinRMconnected
                AV                  = $AV                 
                TamperProt          = $TamperProt         
                AntiMalware         = $AntiMalware        
                AntiSpyware         = $AntiSpyware        
                BehavMon            = $BehavMon           
                OfficeAV            = $OfficeAV           
                NIS                 = $NIS                
                AccessProt          = $AccessProt         
                RealTimeProt        = $RealTimeProt       
                Finished            = $Finished
            }
    

    Is there easy and elegant way to get output consisting of NAME and LAST_LOGON_TIME

        $computername = ($computerArray | Where-Object {($_.WinRMConnected -ne 'True') -and ($_.Managed -ne 'True')}).ComputerName
        $lastActivity = [datetime]::FromFileTime((Get-ADComputer -Filter 'Name -eq [COMPUTER NAME FROM ABOVE]' -Properties *).lastLogonTimestamp)
    

    , one by one?

    The best way I figured is to create hash table (using foreach - going through all computers in array) of these two values and then print it. 

    TahnX a lot for any idea.

    Murphy

    Tuesday, February 25, 2020 1:01 PM

Answers

  • I imported the csv and tried your code:

    # DB IMPORT
        [Collections.Generic.List[PSObject]]$computerArray = @()
        if (Test-Path -Path '.\ArrayOfComputers.csv'){
            $computerArray = Import-Csv '.\ArrayOfComputers.csv'
            $computerArray = $computerArray | Sort-Object ComputerName -Unique
            Write-Host '$ArrayOfComputers.csv imported.'
        }
    
    $computerArray | 
        ForEach-Object{
            $computer = Get-AdComputer $_.ComputerName -Properties LastLogonDate
            $_.Add('XXXLastLogonDate',$_.LastLogonDate)
            $_
        }
    

    and got this error:

    Method invocation failed because [System.Management.Automation.PSCustomObject] doe
    s not contain a method named 'Add'.
    At line:14 char:9
    +         $_.Add('XXXLastLogonDate',$_.LastLogonDate)
    +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (Add:String) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound

    So I modified the code:

        $computerArray | 
        ForEach-Object{
            if (($_.WinRMConnected -ne 'True') -and ($_.Managed -ne 'True')) {
            $computer = Get-AdComputer $_.ComputerName -Properties LastLogonDate
            ($computer.Name).PadRight(25)+$computer.LastLogonDate
            }
        }

    and thats what I needed:

    computer1                  2/19/2020

    computer2                  01/11/2019

    computer3                  02/20/2020

    ...


    • Marked as answer by Murphy__ Wednesday, February 26, 2020 1:47 PM
    Wednesday, February 26, 2020 1:46 PM

All replies

  • Hi Murphy_

    You're right.

    First Gather information and put in a var
    $Result = foreach ($comp in $computers)
    {
    # Populate your PSCustom Object
    }
    The $result is an Array with your Custom Headers (defined in your PSObject)
    Then select the properties you would like to show with Select-Object cmdlet and export as you want.
    $Result | Select-Object -Property ComputerName, LastActivity |
        Out-GridView
        Out-file
        Export-csv

    Regards

    Olivier

    Tuesday, February 25, 2020 1:15 PM
  • Hello, the problem is, that $lastActivity is not included in $computerArray, which is everytime imported from .csv.  And I cannot change content of .csv - add another column. ;-(

    What I wanted to find is solution of list computernames in one column and calculat in the meantime second column, without creating another data structure.  If this is not possible, I'll try to find, if there is not any way, how to change source .csv at the end... 

    Wednesday, February 26, 2020 8:13 AM
  • I cannot tell if the problem is one of language or lack of technical understanding but it is extremly difficult to undersnd what you are trying to ask.

    This is my best guess as to what yo are trying to do;.

    $computerArray |
        ForEach-Object{
            $computer = Get-AdComputer $_.ComputerName -Properties LastLogonDate
            $_.Add('LastLogonDate',$_.LastLogonDate)
            $_
        }
    


    \_(ツ)_/

    Wednesday, February 26, 2020 12:54 PM
  • I imported the csv and tried your code:

    # DB IMPORT
        [Collections.Generic.List[PSObject]]$computerArray = @()
        if (Test-Path -Path '.\ArrayOfComputers.csv'){
            $computerArray = Import-Csv '.\ArrayOfComputers.csv'
            $computerArray = $computerArray | Sort-Object ComputerName -Unique
            Write-Host '$ArrayOfComputers.csv imported.'
        }
    
    $computerArray | 
        ForEach-Object{
            $computer = Get-AdComputer $_.ComputerName -Properties LastLogonDate
            $_.Add('XXXLastLogonDate',$_.LastLogonDate)
            $_
        }
    

    and got this error:

    Method invocation failed because [System.Management.Automation.PSCustomObject] doe
    s not contain a method named 'Add'.
    At line:14 char:9
    +         $_.Add('XXXLastLogonDate',$_.LastLogonDate)
    +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (Add:String) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound

    So I modified the code:

        $computerArray | 
        ForEach-Object{
            if (($_.WinRMConnected -ne 'True') -and ($_.Managed -ne 'True')) {
            $computer = Get-AdComputer $_.ComputerName -Properties LastLogonDate
            ($computer.Name).PadRight(25)+$computer.LastLogonDate
            }
        }

    and thats what I needed:

    computer1                  2/19/2020

    computer2                  01/11/2019

    computer3                  02/20/2020

    ...


    • Marked as answer by Murphy__ Wednesday, February 26, 2020 1:47 PM
    Wednesday, February 26, 2020 1:46 PM
  • The array cannot be empty.  This is where your language issue gives us trouble.  You claim to have an array of objects but it appears that your array is empty. You then import a CSV and want to edit it and add fields.  The array from a CSV cannot be expanded as it it was a pscustomobject.  To edit an CSV we have to do this:

    Import-Csv .\ArrayOfComputers.csv | Select-Object *,LastLogonDate
       ForEach-Object{
            $computer = Get-AdComputer $_.ComputerName -Properties LastLogonDate
            $_.LastLogonDate = $computer.LastLogonDate
            $_
        }

    Note that we can extend the row columns by just adding them as a new column in the import by selecting all columns and adding any new columns.

    Of course none of this code addresses exceptions and is only a best guess as to what you are trying to do.

    Part of the issue is that you have too little knowledge of PowerShell and programming.  You have apparently seen some things and have guessed, incorrectly, that they have something to do with what you want to do.  This makes it hard for you to correctly describe your mission and makes it hard for us to understand what you are asking.


    \_(ツ)_/

    Wednesday, February 26, 2020 2:00 PM
  • You guessed incorrectly - I do not want and I cannot modify the csv format. I already have written. So any advice to change the csv is offtopic.

    I have the array - first time I have created it,

    at the end of each loop I'm saving it

    Next time I use the script, I only import already created array - like it was written here. 

    So there is no empty array, or what you fabulated.

    ThanX for your help, because from your faulty code I got an idea, how to code it.

    But next time, I'll be much more happy without your answers.

    Bye.

    Wednesday, February 26, 2020 2:38 PM
  • The code I posted does not modify the CSV.  It just updates the result with the needed field and outputs a set of custom objects.  If you actually run teh code you will see that.

    Your question is really to vague to be able to provide a better answer.  You will have to l3earnPowerSHell in order to be able to unde5rstand the code and why your issue is vague.


    \_(ツ)_/

    Wednesday, February 26, 2020 5:19 PM
  • Your code produced the error I already posted here. The command was not interpreted, so I cannot test it.

    I found other way myself, so take this problem as solved.

    Thursday, February 27, 2020 1:54 PM