Home > Net >  Return Values of Single Column in PowerShell Array
Return Values of Single Column in PowerShell Array

Time:09-24

I'm creating a PowerShell script for DPM which outputs offsite ready tapes. The below code takes a few seconds to complete the DPM connection and to return the query, which is fine.

# Connect to local DPM server
$DPMServer = $env:COMPUTERNAME
Connect-DPMServer -DPMServerName $DPMServer | Out-Null

# Get the DPM libary
$DPMLib = Get-DPMLibrary

#Format output
$Formatting = @{Expression={$_.Barcode}; Label="Barcode "; Width=12}, 
     @{Expression={"{0:MM/dd/yyyy HH:mm tt}" -f $_.CreationDate}; Label="Creation Date      "; Width=23}, 
     @{Expression={$_.DisplayString}; Label="Tape Label              "; Width=28}, 
     @{Expression={"{0,15:N0}" -f $_.DataWrittenDisplayString}; Label="Data Written   "}

#Calculate Monday at midnight of this week
$Monday = (Get-Date).AddDays((-1 * (Get-Date).DayOfWeek.Value__)   1).Date

# Get specific tapes
$Tapes = Get-DPMTape -DPMLibrary $DPMLib | 
    Where-Object {$_.Barcode -notlike "CLN*"} |
    Where-Object {$_.DisplayString -notlike "Free"} |
    Where-Object {$_.CreationDate -gt $Monday} |
    Sort-Object Barcode |
    Format-Table -Property $Formatting

Write-Host "`nOffsite Ready Tapes:" -ForegroundColor Cyan

#Output tapes
$Tapes

This outputs like so:

PowerShell Output

My question is how do I now select just the barcodes listed within the $Tapes array, and output them (below what I already have) as a comma delimited list, without running the DPM query again. I've tried all sorts of things with no luck, I'm missing something obvious.

If I do a second connection to DPM, I can do it like this, but I'm trying to avoid doubling the time it takes to run. This is part of my original newbie script that I'm trying to better.

# Define DPM server to connect to
$DPMServer = $env:COMPUTERNAME
Connect-DPMServer -DPMServerName $DPMServer | Out-Null

# Get the DPM libary
$DPMLib = Get-DPMLibrary

# Get tape display strings and barcodes, sort by barcode
$Tapes = Get-DPMTape -DPMLibrary $DPMLib | Select-Object CreationDate, DisplayString, Barcode | Sort-Object Barcode

# Create empty array
$DPMTapesForOffsite = @()

Write-Host "`nOffsite Ready Tapes:`n" -ForegroundColor Cyan

foreach ($_ in $Tapes) {
    # Exclude cleaning tapes
    if ($_.Barcode -notlike "CLN*") {
        # Exclude marked as free
        if ($_.DisplayString -notlike "Free") {
            $TimeStamp = Get-Date $_.CreationDate
            # Timestamp is from this week
            if ($Timestamp -gt $Monday) {
                $DPMTapesForOffsite = $DPMTapesForOffsite   $_.barcode
                Write-Host $_.barcode
            }
        }
    }
}

# Format tape list as comma delimited
$DPMTapesForOffsite = $DPMTapesForOffsite -join ","

I'm missing some obvious, any help would greatly be appreciated.

CodePudding user response:

# Omit Format-Table initially, so as to store actual *data* in $tapes,
# not *formatting instructions*, which is what Format-* cmdlets return.
$tapes = Get-DPMTape -DPMLibrary $DPMLib | 
    Where-Object {$_.Barcode -notlike "CLN*"} |
    Where-Object {$_.DisplayString -notlike "Free"} |
    Where-Object {$_.CreationDate -gt $Monday} |
    Sort-Object Barcode

# Now you can apply the desired formatting.
Write-Host "`nOffsite Ready Tapes:" -ForegroundColor Cyan
$tapes | Format-Table -Property $Formatting

# Thanks to PowerShell's member enumeration feature,
# accessing property .Barcode on the entire $tapes *collection* 
# conveniently returns its *elements'* property values.
# -join ',' joins them with commas.
$tapes.Barcode -join ','

Format-* cmdlets output objects whose sole purpose is to provide formatting instructions to PowerShell's output-formatting system - see this answer.
In short: only ever use Format-* cmdlets to format data for display, never for subsequent programmatic processing.

This answer explains member enumeration.

  • Related