Freitag, 28. Mai 2010

A Problem with Remove-Item $folder -recurse -force

I'm working with some testsenario, where I have repeatedly to remove a folder structure of about 3500 files of depth 8.

Remove-Item $folder -recurse -force

sometimes does not remove all the files. In some cases it yields the message, that a folder can't be deleted, because it is not empty, but when checking the folder is empty. In other not all files are removed.

To reach a clean state, I wrote the following script:


function Remove-ItemRecursiveBruteForce            
{            
    param(            
        [Parameter(Position = 0, Mandatory=$true, ValueFromPipeline=$false)]            
        [string]$folder,            
        [Parameter(Position = 1, Mandatory=$False, ValueFromPipeline=$false)]            
        $maxiterations = 20            
    )            
            
    $iteration = 0            
    while (  $iteration++ -lt   $maxiterations)            
    {            
        if (Test-Path $folder)            
        {            
            Remove-Item $folder -recurse -force -EA SilentlyContinue            
        }            
        else            
        {            
            "$folder deleted in $iteration iterations"            
            break            
        }            
    }            
    if (Test-Path $folder)            
    {            
        "$folder not empty after $iteration iterations"            
    }            
            
}            
            


I observe that it needs randomly between 2 and 11 iterations to remove my folder.

I'm using W7-32 bit and use PowerShell-ISE to run the script.

Is this problem just me, or is it OS specific. Any explanations?

Mittwoch, 19. Mai 2010

1. Attemp to use .NET isolated storage with modeless WPK windows

 

The following attempt is not working with modeless windows (replace -show #-asjob    by -asjob). Using -show it works. Please run the code, do some selection within GUI, finally call  Get-value to check the result.


ipmo WPK                        
            
                        
$env:WPKResult = "auto"            
            
function action            
{            
    param (            
        $value            
    )            
    $env:WPKResult = $value            
                
    $changedProperty = $value            
    Write-Host "Value of $changedProperty changed to $value"                        
            
    try {            
    $useriStorage = [System.IO.IsolatedStorage.IsolatedStorageFile]::GetUserStoreForAssembly()            
    $file = New-Object System.IO.IsolatedStorage.IsolatedStorageFileStream("SQLSettigs.xml",[System.IO.FileMode]::Create,$useriStorage)            
    $xml = New-Object System.Xml.Serialization.XmlSerializer($changedProperty.GetType())            
    $xml.Serialize($file,$changedProperty)            
    $file.Close()            
    $useriStorage.Close()            
    }            
    catch {            
        $env:WPKResult = 'error'            
    }            
            
}            
                          
New-StackPanel {                        
    New-RadioButton -Content "auto"     -GroupName Results -IsChecked $True -On_Click { action "auto" }                        
    New-RadioButton -Content "list"     -GroupName Results -On_Click { action "list" }                        
    New-RadioButton -Content "table"    -GroupName Results -On_Click { action "table" }            
    New-RadioButton -Content "grid"     -GroupName Results -On_Click { action "grid" }            
    New-RadioButton -Content "variable" -GroupName Results -On_Click { action "variable" }            
    New-RadioButton -Content "csv"      -GroupName Results -On_Click { action "csv" }            
    New-RadioButton -Content "file"     -GroupName Results -On_Click { action "file" }            
} -show #-asjob                        
                        
            
function Get-value            
{            
    $useriStorage = [System.IO.IsolatedStorage.IsolatedStorageFile]::GetUserStoreForAssembly()            
    try {            
        $file = New-Object System.IO.IsolatedStorage.IsolatedStorageFileStream("SQLSettigs.xml",[System.IO.FileMode]::Open,$useriStorage)            
    }            
    catch {            
        Write-Host "UISettings.xml is not found"            
        return            
    }                        
    $xmlReader = New-Object System.Xml.XmlTextReader($file)            
    $xml = New-Object System.Xml.Serialization.XmlSerializer('abc'.GetType())            
    $newISEOptions = $xml.Deserialize($xmlReader)            
    $newISEOptions            
}

Sonntag, 16. Mai 2010

Please help - I want to send back a keystroke to the ISE window

Hello WPF friends, I need a little help. I want to add a button which sends F7 keystroke to the ISE-window from which I run this little WPK script.


ipmo WPK                        
                        
$env:WPKResult = "auto"                          
New-StackPanel {                        
    New-RadioButton -Content "auto"     -GroupName Results -IsChecked $True -On_Click { $env:WPKResult = "auto" }                        
    New-RadioButton -Content "list"     -GroupName Results -On_Click { $env:WPKResult = "list" }                        
    New-RadioButton -Content "table"    -GroupName Results -On_Click { $env:WPKResult = "table" }            
    New-RadioButton -Content "grid"     -GroupName Results -On_Click { $env:WPKResult = "grid" }            
    New-RadioButton -Content "variable" -GroupName Results -On_Click { $env:WPKResult = "variable" }            
    New-RadioButton -Content "csv"      -GroupName Results -On_Click { $env:WPKResult = "csv" }            
    New-RadioButton -Content "file"     -GroupName Results -On_Click { $env:WPKResult = "file" }            
    New-Button -Content "execute Sql"  -On_click { New-Button "I want to send F7 key-stroke to calling ISE" -show }                        
} -asjob                        
                        

This script is intended to be run in ISE and to add some cool GUI to SQLPSX.

Thanks

Bernd

Mittwoch, 12. Mai 2010

A try in WPK (one way and only once)

The best I found in WPK seems to be the the following:

ipmo WPK            
            
$option = "To File" # this value might be prompted by the user            
             
             
New-StackPanel {            
    New-RadioButton -Content "To Text" -GroupName Results -IsChecked $True -On_Click {             
        $Resource.Result = "To Text"             
        $info = $window | Get-ChildControl info            
        $info.text = $Resource.Result            
        $env:WPKResult = $Resource.Result            
        }            
    New-RadioButton -Content "To Grid" -GroupName Results -On_Click {              
        $Resource.Result = "To Grid"             
        $info = $window | Get-ChildControl info            
        $info.text = $Resource.Result            
        $env:WPKResult = $Resource.Result            
        }            
    New-RadioButton -Content "To File" -GroupName Results -On_Click {              
        $Resource.Result = "To File"             
        $info = $window | Get-ChildControl info            
        $info.text = $Resource.Result            
        $env:WPKResult = $Resource.Result            
    }            
    New-RadioButton -Content "To CSV" -GroupName Results -On_Click {              
        $Resource.Result = "To CSV"             
        $info = $window | Get-ChildControl info            
        $info.text = $Resource.Result            
        $env:WPKResult = $Resource.Result            
    }            
    New-textBox -Name info             
    } -On_Loaded {            
            $info = $window | Get-ChildControl info            
            $info.text = $Resource.Result            
    }-asjob -resource @{Result = $option}            
            

I can modify the value within GUI and query it outside

$env:WPKResult
 
I misuse the processes environment, which is shared between the runspaces. Hmm better than pidgeon carrying USB sticks, but it is restricted to strings.

I guess I have to really dive into PowerBoots  (and that is the polite version ;-) of my opinion about WPK)

Have some fun trying to find further work arounds.

Bernd

 
 
 

A small Async PowerBootsWindow

Hello,
here I'll show a little async PowerBoots Gui, which is able to modify variables in the main thread.

ipmo PowerBoots            
            
$options = @{ "Results" = "To Text" }            
             
Boots {             
    StackPanel {            
        RadioButton -Content "To Text" -GroupName Results -IsChecked $True -On_Click { $options.Results = "To Text" }            
        RadioButton -Content "To Grid" -GroupName Results -On_Click {  $options.Results = "To Grid" }            
        RadioButton -Content "To File" -GroupName Results -On_Click {  $options.Results = "To File" }            
        RadioButton -Content "To CSV" -GroupName Results -On_Click {  $options.Results = "To CSV" }            
                }            
      } -async            
            
            

Is it possible to do the same thing with WPK?

A viewer for Crystal Reports with PowerShell (partially working)

Hello,
this time I tried to build a small Report Viewer using the components from Visual Studio 2008 with PowerShell. It shows that using PowerShell here makes some things rather easy.

I'm using this to display old Reports made with Crystal Reports 8.5 using ODBC Datasources to SQL-Server.

Reports based on views works fine, I can set database and formulars.

But I have still a problem with reports based on stored procedures. Setting $table.location doesn't work anymore as in the past. I go the error table not found. Any hints welcome.

And here is the code if you want to try something like this:

Function Show-CrystalReport            
{            
    param(            
        $reportPath,             
        $servername,             
        $databasename,             
        $userId,             
        $password,            
        $RecordSelectionFormula,            
        $formulas,            
        $parameters            
        )            
                    
            
    [reflection.assembly]::LoadWithPartialName('CrystalDecisions.Shared')            
    [reflection.assembly]::LoadWithPartialName('CrystalDecisions.CrystalReports.Engine')            
    [reflection.assembly]::LoadWithPartialName('CrystalDecisions.Windows.Forms')            
            
    $report = New-Object CrystalDecisions.CrystalReports.Engine.ReportDocument            
    $report.load($reportPath)            
            
    $report.ParameterFields | % {             
        if ($parameters.keys -contains $_.Name)            
        {            
            $report.SetParameterValue($_.Name, $parameters[$_.Name])            
        }            
     }               
            
    $report.DataDefinition.FormulaFields | % {            
        if ($formulas.keys -contains $_.Name)            
        {            
            $_.Text = $formulas[$_.Name]            
        }            
    }            
            
    if ($RecordSelectionFormula) {            
        $report.RecordSelectionFormula = $RecordSelectionFormula            
    }            
            
    foreach ($Table in $report.Database.Tables)            
    {            
        $table            
        $tli = $Table.LogonInfo            
        $li = $tli.ConnectionInfo            
        Write-host "location : $($table.location)"            
                    
        $li.ServerName = $servername            
        $li.DatabaseName = $databasename             
        $li.UserID = $userId            
        $li.Password = $password            
        $Table.ApplyLogOnInfo($tli)            
        # the following doesn't work as in the past            
        if ( $table.location -contains '.')            
        {            
            $table.location -match  '(.*)\.(.*)'            
            $table.location = "$($databasename).dbo.$($matches[2])"            
        }            
        $table.location             
                   
    }            
            
    $rv = New-Object CrystalDecisions.Windows.Forms.CrystalReportViewer            
    $rv.ReportSource = $report            
    $rv.Dock = [System.Windows.Forms.DockStyle]::Fill            
            
            
    $form = New-Object Windows.Forms.Form            
                 
    $form.Height = 810            
    $form.Width= 1210            
    $form.Controls.Add($rv)            
    $rv.Show()            
    $form.ShowDialog()            
            
    $rv.Dispose()            
    $report.Dispose()            
    $form.Dispose()            
            
}