'Populating a datagridview

I ma working on a form that will search all connected drives for PST files.

I can get it working with the following command:-

Get-PSDrive -PSProvider "filesystem"|%{get-childitem $_.root -include *.pst -r}|select name, directoryname, @{name="Size (GB)";expression ={"{0:N2}" -f ($_.length/1GB)}}

The only problem is it takes about 45 minutes to run through all the drives and finish the search. I was thinking of trying to speed it up by using the windows search index.

I have got this....

function Searchindex{
$query="SELECT System.ItemName, system.ItemPathDisplay, System.ItemTypeText, System.Size FROM SystemIndex where system.itemtypetext = 'outlook data file'"
$objConnection = New-Object -ComObject adodb.connection
$objrecordset = New-Object -ComObject adodb.recordset
$objconnection.open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';")
$objrecordset.open($query, $objConnection)

$array=@()

Try { $objrecordset.MoveFirst() }
Catch [system.exception] { "no records returned" }
do 
{
 Write-host ($objrecordset.Fields.Item("System.ItemName")).value `
 ($objrecordset.Fields.Item("System.ItemPathDisplay")).value `
 ($objrecordset.Fields.Item("System.ITemTypeText")).value `
 ($objrecordset.Fields.Item("System.Size")).value
 if(-not($objrecordset.EOF)) {$objrecordset.MoveNext()}
} Until ($objrecordset.EOF)


$objrecordset.Close()
$objConnection.Close()
$objrecordset = $null
$objConnection = $null
[gc]::collect()
}

this outputs the details to the screen in a few seconds which is perfect but I can't work out how to display it in a datagrid view.

I am using primal form to create the forms.

Once the data is populated in the datagridview I want to be able to select records and copy them to a new location

Can anyone help?

TIA

Andy



Solution 1:[1]

I'm not familiar with DataGridView but I feel if you had an object you would be better capable to manipulate it.

function Searchindex{
$query="SELECT System.ItemName, system.ItemPathDisplay, System.ItemTypeText, System.Size FROM SystemIndex where system.itemtypetext = 'outlook data file'"
$objConnection = New-Object -ComObject adodb.connection
$objrecordset = New-Object -ComObject adodb.recordset
$objconnection.open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';")
$objrecordset.open($query, $objConnection)

$array=@()

Try { $objrecordset.MoveFirst() }
Catch [system.exception] { "no records returned" }
do 
{
    $array += [pscustomobject]@{
        Name = ($objrecordset.Fields.Item("System.ItemName")).value
        Path = ($objrecordset.Fields.Item("System.ItemPathDisplay")).value 
        TypeText = ($objrecordset.Fields.Item("System.ITemTypeText")).value 
        Size = ($objrecordset.Fields.Item("System.Size")).value
    }

    If(-not($objrecordset.EOF)) {$objrecordset.MoveNext()}
} Until ($objrecordset.EOF)


$objrecordset.Close()
$objConnection.Close()
$objrecordset = $null
$objConnection = $null
[gc]::collect()

$array
}

This will send out a custom PowerShell object array. You already had the variable $array initialized. We just needed to populate it.

Then you could use something like this to filter out the files you are looking for.

Searchindex | Out-GridView -PassThru

After hitting Ok it will only output the records selected.

DataGridView

with multiselect and return

$global:results = @()

#...searchindex function is here ....

$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(900,600)
$dataGridView = New-Object System.Windows.Forms.DataGridView
$dataGridView.Size=New-Object System.Drawing.Size(800,400)
$dataGridView.SelectionMode = 'FullRowSelect'
$dataGridView.MultiSelect = $true
$go = New-Object System.Windows.Forms.Button
$go.Location = New-Object System.Drawing.Size(300,450)
$go.Size = New-Object System.Drawing.Size(75,23)
$go.text = "Select"
$form.Controls.Add($go)
$form.Controls.Add($dataGridView)


$arraylist = New-Object System.Collections.ArrayList
$arraylist.AddRange((Searchindex))
$dataGridView.DataSource = $arraylist


$dataGridView.Columns[0].width = 240

$go.Add_Click(
{
    $dataGridView.SelectedRows| ForEach-Object{
        $global:results += [pscustomobject]@{
            Name = $dataGridView.Rows[$_.Index].Cells[0].Value
            Path = $dataGridView.Rows[$_.Index].Cells[1].Value
            TypeText = $dataGridView.Rows[$_.Index].Cells[2].Value
            Size = $dataGridView.Rows[$_.Index].Cells[3].Value
        }
        $form.Close()
    }

})

$form.ShowDialog() 
$global:results

There is a lot to cover here but look at the examples and let me know how this works for you. It will return all selected rows back as objects in the global variable $global:results. It needs to be global as output does not persist outside the $go.Add_Click. The searchindex function is there but omitted in the second code sample to save space.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community