Вывод из функции powershell показывается только после завершения сценария

# Create ArrayLists to populate
[System.Collections.ArrayList] $sharedmailboxes = @()
[System.Collections.ArrayList] $licensedSMBs = @()

# Get all Shared Mailboxes
Get-MgUser -Filter "usertype eq 'member'" -All | foreach-object { 
    $smb = get-mguser -userid $_.Id -select mailboxsettings | select-object -ExpandProperty MailboxSettings | select-object -ExpandProperty UserPurpose
        if ( $smb -eq "shared" ) { $null = $sharedmailboxes.add($smb) }
}

# Find Licensed Shared Mailboxes and Create Table of licenses
foreach ( $mb in $sharedmailboxes ) { 
    $details = Get-MgUserLicenseDetail -UserId $mb.id | Select-Object @{Name = 'UPN'; Expression = {$mb.UserPrincipalName}},SkuPartNumber
    if ( $null -ne $details){
        $obj = [pscustomobject] @{ name = $mb.UserPrincipalName }
        foreach ( $i in $details ) { $obj | add-member -MemberType NoteProperty -Name $i.SkuPartNumber -Value "X" }
        $null = $licensedSMBs.Add( $obj )
    }
}

if I display the variable $licensedSMBs it only creates two columns,

$licensedSMBs | format-table
name                        IDENTITY_THREAT_PROTECTION  SPE_E3
----                        --------------------------  ------
sharedmailbox1@xyz.com       X                          X
sharedmailbox2@xyz.com       X                          X
sharedmailbox3@xyz.com
sharedmailbox4@xyz.com
name                     POWER_BI_STANDARD
----                     -----------------
sharedmailbox3@xyz.com   x
sharedmailbox4@xyz.com   x

after many hours of trying numerous approaches I finally gave up. My problem is trivial but it gives me really hard time.

I have this function:

function SearchSharedMailboxes {
param (
    [parameter(Mandatory=$true)] $objectList,
    [parameter(Mandatory=$true)] [string]$objectName
)
    
    $matchingList = [System.Collections.ArrayList]::new()

    if ($objectList.Count -le 0) {
        
    $decision = Read-Host "No match found, search again Y/N?"

        if ($decision -eq "Y") {

            GetSharedMailboxes

        } else {

            Exit-PSSession

        }

    } else {

        Write-Verbose "Matches found:"
        
        $i=0
        $objectList | Foreach-Object {

             [PSCustomObject]@{
                ID = $i
                UserPrincipal = $_.UserPrincipalName
                RecipientTypeDetails = $_.RecipientTypeDetails
                PrimarySMTPAddress = $_.PrimarySMTPAddress
                
            }
            $i++

        }

    }
    
}

I expect to see output in the console like this:

ID UserPrincipal                       RecipientTypeDetails PrimarySMTPAddress
-- -------------                       -------------------- ------------------
 0 Name1                               SharedMailbox        [email protected]
 1 Name2                               SharedMailbox        [email protected]
 2 Name3                               SharedMailbox        [email protected]

The thing is that the output shows fine but if I call another function before the final bracket the output shows no more. So to demonstrate:

     $i=0
        $objectList | Foreach-Object {

             [PSCustomObject]@{
                ID = $i
                UserPrincipal = $_.UserPrincipalName
                RecipientTypeDetails = $_.RecipientTypeDetails
                PrimarySMTPAddress = $_.PrimarySMTPAddress
                
            }
            $i++

        }

    }

    ObjectAssigning
    
}

With “ObjectAssigning” function call like above, the output shows no more UNTIL the script ends. So when the “ObjectAssigning” method finishes and therefore whole script ends, it produces output like before. However, I need the output to show up while the script is running, not after it finishes. I tried assigning my custom PSObject to variable and calling the variable, I also tried something like

$variableWithCustomPSObjAssigned | Select-Object -Property *
   $objectList | Foreach-Object {

            $item = New-Object -TypeName PSObject
            $item | Add-Member -MemberType NoteProperty -Name ID -Value $i
            $item | Add-Member -MemberType NoteProperty -Name UserPrincipal -Value $_.UserPrincipalName
            $item | Add-Member -MemberType NoteProperty -Name RecipientTypeDetails -Value $_.RecipientTypeDetails
            $item | Add-Member -MemberType NoteProperty -Name PrimarySMTPAddress -Value $_.PrimarySMTPAddress
            $i++
        }

I would appreciate any help regarding this matter.

Tables display sets of data. They can be fully customized.

A simple example with no frills. Table columns are defined from the data.

Table with Custom Columns

Define custom columns for your table.






Table with Custom Column Rendering

Define column rendering. Sorting and exporting still work for the table.





Table Column Width

Column width can be defined using the -Width parameter. You can also decide to truncate columns that extend past that width.





You can configure custom filters per column. The table supports text, select, fuzzy , slider, range, date , number, and autocomplete filters.






Static Options for Select Filters

When using server-side processing, the available filters may not display the full range of options since the select dropdown only has access to the current page of results. To avoid this, you can use the -Options parameter on New-UDTableColumn.

To enable search, use the -ShowSearch parameter on New-UDTable.

When using custom columns, you will need to add the -IncludeInSearch parameter to the columns you’d like to include in the search.






Table with server-side processing

Property NameTypeDescription

value = ‘filterValue’
}

A list of filter values. Each hashtable has an Id and a Value property.

Property name to sort by.

asc or desc depending on the sort order.

The current page (starting with 0).

The selected page size.

An array of properties being shown in the table.

The total number of records before filtering or paging.








Retrieving Displayed Data









By default, paging is disable and tables will grow based on how many rows of data you provide. You can enable paging by using the -ShowPagination cmdlet (alias -Paging). You can configure the page size using the -PageSize cmdlet.

Disable Page Size All

You can change the location of the pagination control by using the -PaginationLocation parameter. It accepts top, bottom and both.

To enable sorting for a table, use the -ShowSort parameter. When you enable sorting, you will be able to click the table headers to sort the table by clicking the headers. By default, multi-sort is enabled. To multi-hold shift and click a column header.

You can control which columns can be sorted by using New-UDTableColumn and -ShowSort parameter.






Disable Sort Remove

By default, the sorting of a table has 3 states. Unsorted, ascending and descending. If you would like to disable the unsorted state, use the -DisableSortRemove parameter of New-UDTable.

Tables support selection of rows. You can create an event handler for the OnRowSelected parameter to receive when a new row is selected or unselected or you can use Get-UDElement to retrieve the current set of selected rows.

    New-UDTableColumn -Property Name -Title "Service Name" -ShowSort -IncludeInExport -IncludeInSearch -ShowFilter -FilterType text
    New-UDTableColumn -Property Status -Title Status -ShowSort -DefaultSortColumn -IncludeInExport -IncludeInSearch -ShowFilter -FilterType select 




The $EventData variable for the -OnRowSelected event will include all the columns as properties and a selected property as to whether the row was selected or unselected.

For example, the service table data would look like this.










Tables support exporting the data within the table. You can export as CSV, XLSX, JSON or PDF. You can define which columns to include in an export and choose to export just the current page or all the data within the table.





New-UDTable -Id 'service_table' -Data $Data -Columns $Columns -Title 'Services' -ShowSearch -ShowPagination -Dense -Export

Hidden columns allow you to include data that is not displayed in the table but is included in the exported data.





New-UDTable -Id 'service_table' -Data $Data -Columns $Columns -Title 'Services' -ShowSearch -ShowPagination -Dense -Export

In this example, I have a SQL table that contains podcasts. When exporting, you will receive information about the current state of the table to allow you to customize what data is exported.








<# Query will contain

Customizing Export Options





New-UDTable -Id 'service_table' -Data $Data -Columns $Columns -Title 'Services' -ShowSearch -ShowPagination -Dense -Export -ExportOption "csv"

You can use the -TextOption parameter along with the New-UDTableTextOption cmdlet to set text fields within the table.

"Search all these records"

Refresh with a button

You can externally refresh a table by putting the table within a dynamic region and using Sync-UDElement.

This example creates a button to refresh the table.

# Store in the page so we can get the current ID. 
# Using the same ID fails to update when the dynamic reloads.


If you use the -LoadData parameter, you can sync the table directly. This has the benefit of maintaining the table state, such as the page and filtering, after the refresh.







Show Refresh Button

You can use the -ShowRefresh parameter to provide a refresh button for server-side tables.






<# Query will contain

Alternating Row Colors

You can use a theme to create a table with alternating row colors.





PowerShell Format-Table

Introduction to PowerShell Format-Table

Before we dive into the details, let’s start with the basics. PowerShell Format-Table is a command that allows you to display your output in a table format. This makes it easier to read, sort, and filter your data. The command is simple to use and can be customized to fit your specific needs. In addition, It allows for customization of column widths, sorting, and displaying calculated values.

One of the biggest advantages of using PowerShell Format-Table is that it simplifies complex data structures. For example, if you have a complex object with multiple properties, it can be difficult to read the output in the default format. Format-Table allows you to select the properties you want to display and format them in a clear and concise manner.

Benefits of using PowerShell Format-Table

There are several benefits to using PowerShell Format-Table. One of the main advantages is that it allows you to customize your output to fit your specific needs. You can select the properties you want to display, format them, and even adjust the column width to fit your data.

Another advantage of using PowerShell Format-Table is that it makes it easier to sort and filter your data. You can sort your data by any column, and you can filter your data using the Where-Object command.

PowerShell Format-Table also allows you to export your output to a CSV file, which can be useful for sharing your data with others or importing it into another application.

Understanding the PowerShell output to table

Before we dive into the specifics of PowerShell Format-Table, it’s important to understand how PowerShell outputs data. By default, PowerShell outputs data as a series of objects. These objects can have different properties, which can be displayed using the Get-Member command.

Format-Table 
[-Property] <String[]> 
[-AutoSize] 
[-Wrap] 
[-RepeatHeader] 
[-GroupBy <Object[]>] 
[-HideTableHeaders] 
[-InputObject <PSObject>] 
[-Property <String[]>] 
[-Expand <String[]>] 
[-ShowError] 
[-DisplayError] 
[-View <TableControl>] 
[<CommonParameters>]

The Format-Table cmdlet consists of several parameters that enable you to customize the output data. Here is the breakdown of important parameters:

ParameterDescription
-PropertyThe property parameter specifies which properties of the objects should be displayed in the table.
-AutoSizeAutomatically adjusts the column width to fit the data.
-WrapUse the -Wrap parameter to wrap the text in the columns to next line to fit the column width.
-GroupByThe parameter groups the data by a specified property.
-HideTableHeadersHides the table headers.
-InputObjectSpecifies the input data.

Formatting output with PowerShell Format-Table

Now that we understand the basics of PowerShell output and Format-Table, let’s dive into the specifics of how to format your output. The Format-Table command has several options that allow you to customize your output.

To get started, let’s look at a basic example. Suppose we want to list services on the computer with certain properties:

Get-service | select -Property Name, CanShutdown, CanStop, DisplayName, Status, StartType -First 5

This will list each property specified and create an output in the list format below:

PowerShell Format Table

We then pipe the array to Format-Table and specify the properties we want to display. The output should look like this:

Get-service | select -Property Name, CanShutdown, CanStop, DisplayName, Status, StartType -First 10 | Format-Table
Format-Table in PowerShell

Select Specific columns from the Output

You can use the Format-Table cmdlet to select specific columns from the output of the previous cmdlet. Say, for example, We are interested in seeing only selected properties of the object, such as Name, Last modified Time, last accessed time, and Creation time of the files and folders:

Get-ChildItem -Path C:\Windows\System32 | Format-table -Property Name, LastAccessTime,LastWriteTime,CreationTime

Adjusting column width in PowerShell Format-Table

In some cases, the default column width may not be sufficient to display your data. Fortunately, PowerShell Format-Table allows you to adjust the column size using the -AutoSize parameter. This parameter adjusts the column widths to minimize truncation and use as little width as possible while displaying all content. This is particularly useful when you are working with columns of data with varying lengths, and you want to see as much of the data as possible without a lot of empty space.

For example, suppose we need to retrieve the list of processes that start with “Windows” in their names:

Get-Service -DisplayName Windows* | Format-Table

This code retrieves a list of processes with three columns. However, certain text in the columns is truncated to fit the screen width. You can also use the alias FT.

PowerShell Format-table without autosize

We can pipe this output to Format-Table and use the -AutoSize parameter to adjust the column width:

Get-Service -DisplayName Windows* | Format-Table -AutoSize

The output of PowerShell ft should look like this on the command line:

Format-table with Autosize

The -AutoSize parameter automatically adjusts the column width to fit the data. This means that columns with longer data will be wider than columns with shorter data. This ensures that no information is truncated or hidden.

Get-Service | Select-Object Name, DisplayName, Status | 
     Format-Table -Property Name,@{Expression={$_.DisplayName};Label="Title";Width=10}, @{Expression={$_.Status};Label="Service Status";Width=10}
format table width

The -Wrap parameter allows you to create tables that span multiple lines. Here is an example:

Format table wrap

Exporting PowerShell output to CSV with Format-Table

However, the Format-Table is primarily for formatting output for the console display. When you want to export data to a CSV, you should work with raw objects (like those returned by Select-Object) and pass them directly to Export-Csv. To export PowerShell output to CSV with Format-Table, simply pipe the output from Select-Object to the Export-Csv cmdlet. You can specify the name and location of the CSV file using the -Path parameter.

Here’s how you could achieve this:

# Fetch the installed software details
$softwareInfo = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where {$_.DisplayName -Ne $Null}

#Display the Result in console with Format-Table
$softwareInfo | Format-Table DisplayName, DisplayVersion, Publisher

# Export the information to a CSV file
$softwareInfo | Select-Object DisplayName, DisplayVersion, Publisher | Export-Csv -Path 'C:\Temp\InstalledSoftware.csv' -NoTypeInformation

The important point to note here is that you don’t use Format-Table when exporting to a CSV file. Using Format-Table before Export-Csv would be inappropriate and would not yield the expected CSV output.

Sorting data in PowerShell Format-Table

Sorting data in PowerShell Format-Table is a useful feature that allows you to quickly identify trends and patterns in large sets of data. By default, PowerShell Format-Table will sort data based on the first column of the table. However, you can also sort data based on other columns by using the Sort-Object cmdlet.

Get-Process | Select-Object Name, CPU, WorkingSet | Sort-Object -Property CPU -Descending | Format-Table

Output in PowerShell console:

Format-table sort
Get-Process | Where-Object { $_.WorkingSet -gt 1GB } | Format-Table

This will filter the list of processes and only display those with a working set size greater than 1GB. By combining sorting and filtering with the formatting capabilities of Format-Table, you can easily manipulate and display your data in a way that is both visually appealing and informative.

GroupBy Parameter in Format-Table cmdlet

The GroupBy parameter in Format-Table separates the output into tables based on a property value. To use GroupBy, the result of the original command needs to be piped to Sort-Object first. This allows for creating separate tables for each group based on a specific property.

Get-Process | Sort-Object -Property basepriority | Format-Table -GroupBy basepriority -Wrap
Format-Table GroupBy

Here is another example of group services by their status:

Get-Service | Format-Table -Property Name, Status -GroupBy Status

How to Use Format-Table Expressions to Create Custom Columns?

Get-Service | Select-Object Name, DisplayName, Status | 
     Format-Table -Property Name,@{Expression={$_.DisplayName};Label="Title"}, @{Expression={$_.Status};Label="Service Status"}

Here is another example of creating a new column with the calculation:

Get-Process | Where {$_.StartTime -ne $null} | 
    Format-Table ProcessName, @{Label="Running Time"; Expression={(get-date) - $_.StartTime}}
Format-table expressions

In this example, we have added a calculated property, “Running Time” to find the total running time. Here is another example of adding custom columns using calculated properties.

Get-Process | Format-Table Name, Id, @{Name="Memory (MB)"; Expression={[math]::round($_.WS / 1MB, 2)}}

Wrapping up

How to format the PowerShell command output as a table?

How do I sort a format table in PowerShell?

How do I use custom headers in the PowerShell output table?

How to use the PowerShell format list?

What is format-wide in PowerShell?

Can I adjust the column sizes automatically?

Yes, you can use the -AutoSize parameter to adjust the column size and number of columns based on the width of the data.

Can I filter the output in Format-Table?

How do I handle wide output in Format-Table?

If the output is wider than the console, Format-Table will truncate it by default. You can use the -Wrap parameter to display text that exceeds the column width on the next line.

What is the difference between Format-Table and Format-List?

Format-Table formats the output as a table, while Format-List formats it as a list. Use Format-Table when you want to display data in a tabular format, and Format-List when you want to display detailed information about each object.

How can I save the formatted table output to a file?

How can I hide the table headers?

How do I specify the properties to display in the table?

I need specific fields from Get-Volume. Tried using Format-Table:

PS C:\Users\saukrs> Get-Volume | Format-Table -Property DriveLetter, FriendlyName, FileSystemType, DriveType, OperationalStatus, SizeRemaining, Size

DriveLetter FriendlyName FileSystemType DriveType OperationalStatus SizeRemaining          Size
----------- ------------ -------------- --------- ----------------- -------------          ----
          E              Unknown        Fixed     OK                 244047036416  244047675392
          C              NTFS           Fixed     OK                    145694720  255405891584
          D              NTFS           Fixed     OK                   1708548096 1000186310656
                         NTFS           Fixed     OK                     86540288     529526784

I expected them to be like in the original content. Please see drive letters C and D:

PS C:\Users\saukrs> Get-Volume | Format-Table

DriveLetter FriendlyName FileSystemType DriveType HealthStatus OperationalStatus SizeRemaining      Size
----------- ------------ -------------- --------- ------------ ----------------- -------------      ----
E                        Unknown        Fixed     Healthy      OK                    227.29 GB 227.29 GB
C           pagrindinis  NTFS           Fixed     Healthy      OK                     141.2 MB 237.87 GB
D           New Volume   NTFS           Fixed     Healthy      OK                      1.59 GB  931.5 GB
                         NTFS           Fixed     Healthy      OK                     82.53 MB    505 MB

Why is that? And how can this be fixed, please?

In fact, Out-GridView is a wrapper to run .NET DataGridView, a standard graphical form from a Windows Form Control.

Using Out-GridView Tables

Let’s look at the simplest example of using the Out-GridView cmdlet to display a list of Windows services and some of their properties:

Using Out-GridView tables in PowerShell

As you can see, a graphic table form with the list of Windows service properties appeared. The cmdlet sets column names automatically based on the object properties or data type, and extends PSObject properties if data format cannot be defined.

You can search the form using the Filter box.

search in out-gridview

You can also use the Add criteria button to search the table. In the screenshot below, I have created the simplest filter with a list of running services having VMW in their names. The filter is created based on the values of object properties directly.

add a criteria in out-gridview in order to filter results

Or let’s display a list of TOP 10 processes with the highest CPU utilization (I have changed the name of my Out-GridView window using the –Title option):

You can quickly sort the table contents in ascending/descending order by clicking the column header.

Powershell Out-GridView sorting

Out-GridView cmdlet with PassThru Switch

PowerShell Out-GridView cmdlet with PassThru Switch

processing Out-GridView output

-OutputMode Single and -OutputMode Multiple

Press and hold Ctrl to select multiple rows in the table.

How to Use Out-Gridview as a GUI in PowerShell Script?

Here are some more interesting examples of using Out-GridView.

To display a list of previous commands from the PowerShell history and run the selected commands again:

To display a list of additional Windows components and install selected (for example, RSAT Active Directory management tools and the SSH client):

Select-Object with Out-GridView

Using the Invoke-Command, you can get data from remote computers and show them in a table:

out-gridview : To use the Out-GridView, install Windows PowerShell ISE by using Server Manager, and then restart this application. (Could not load file or assembly 'Microsoft.PowerShell.GraphicalHost, Version=3.0.0.0, Culture=neutral, PublicKeyToken=xxxxx' or one of its dependencies. The system cannot find the file specified.)

However, you can use the –ComputerName option many cmdlets have to access Server Core. For example:

For some reason, Microsoft removed the Out-GridView cmdlet from PowerShell Core 6.x, but returned it in version 7.0. If you are using PowerShell 6.x, update it to the latest version using this command:

As you can see, Out-GridView allows adding a nice graphical interface to your PowerShell scripts.

functions/public/Open-PSWorkItemConsole.ps1

‘The path to the PSWorkItem SQLite database file. It must end in .db’

“Could not validate the database path.”

:/>  Сбивается время на компьютере Windows 10: постоянно неправильно показывает в трее

Оставьте комментарий