Author Archives: suneworld

Keyboard Tricks for Launching PowerShell

PowerTip of the Day, from PowerShell.com:

If you have pinned PowerShell to your taskbar (on Windows 7: launch PowerShell, right-click its icon in the task bar, choose “Pin this program to taskbar”), then a click on the icon will open PowerShell. Here are three neat tricks:
First, move the pinned PowerShell icon with your mouse to the leftmost position in your taskbar. Yes, icons are movable! Now, press WIN+1. PowerShell will launch or jump into the foreground, just as if you had clicked the PowerShell icon.
Next, press SHIFT+WIN+1 (or hold SHIFT while you click your PowerShell icon). You get a new PowerShell window.
Finally, hold CTRL+SHIFT+WIN+1 (watch your fingers). This time, PowerShell starts elevated (provided Windows uses UAC).
As you may have guessed, the number reflects the icon position, so pressing a “2” instead of a “1” applies your keyboard magic to the second icon in your taskbar.

Using PowerShell ISE with Full Privileges

PowerTip of the Day, from PowerShell.com:

Sometimes you need full administrator privileges to debug or test a script in the ISE script editor. By default, ISE starts with restricted privileges (when Windows User Account Control (UAC) is enabled).

To launch ISE with full privileges, right-click the PowerShell icon in your taskbar, and hold CTRL+SHIFT while you click on it. This key shortcut works for anything you click and invokes the UAC elevation dialog.

Implicit Foreach in PSv3

PowerTip of the Day, from PowerShell.com:

PowerShell v3 Beta is available for quite some time now, so every now and then we start tossing in some PowerShell v3 tips. We’ll clearly mark them as such since they only run on PowerShell v3, not v2. This is something new in PowerShell v3:

When you work with array data, in previous PowerShell versions you had to loop through all elements to get to their properties and methods. No more in PowerShell v3. PowerShell now detects that you are working with an array and applies your call to all array elements. So with this line you could gracefully close all running notepad.exe.

(Get-Process notepad).CloseMainWindow()

Previously, you would have had to write:

Get-Process notepad | ForEach-Object { $_.CloseMainWindow() }

Export-CSV with append

function Export-CSV {
[CmdletBinding(DefaultParameterSetName='Delimiter',
  SupportsShouldProcess=$true, ConfirmImpact='Medium')]
param(
 [Parameter(Mandatory=$true, ValueFromPipeline=$true,
           ValueFromPipelineByPropertyName=$true)]
 [System.Management.Automation.PSObject]
 ${InputObject},
 [Parameter(Mandatory=$true, Position=0)]
 [Alias('PSPath')]
 [System.String]
 ${Path},

 #region -Append (added by Dmitry Sotnikov)
 [Switch]
 ${Append},
 #endregion 
 [Switch]
 ${Force},
 [Switch]
 ${NoClobber},
 [ValidateSet('Unicode','UTF7','UTF8','ASCII','UTF32',
                  'BigEndianUnicode','Default','OEM')]
 [System.String]
 ${Encoding},
 [Parameter(ParameterSetName='Delimiter', Position=1)]
 [ValidateNotNull()]
 [System.Char]
 ${Delimiter},
 [Parameter(ParameterSetName='UseCulture')]
 [Switch]
 ${UseCulture},
 [Alias('NTI')]
 [Switch]
 ${NoTypeInformation})
begin
{
 # This variable will tell us whether we actually need to append
 # to existing file
 $AppendMode = $false

 try {
  $outBuffer = $null
  if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
  {
      $PSBoundParameters['OutBuffer'] = 1
  }
  $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Export-Csv',
    [System.Management.Automation.CommandTypes]::Cmdlet)

 #String variable to become the target command line
 $scriptCmdPipeline = ''
 # Add new parameter handling
 #region Dmitry: Process and remove the Append parameter if it is present
 if ($Append) {

  $PSBoundParameters.Remove('Append') | Out-Null

  if ($Path) {
   if (Test-Path $Path) {        
    # Need to construct new command line
    $AppendMode = $true

    if ($Encoding.Length -eq 0) {
     # ASCII is default encoding for Export-CSV
     $Encoding = 'ASCII'
    }

    # For Append we use ConvertTo-CSV instead of Export
    $scriptCmdPipeline += 'ConvertTo-Csv -NoTypeInformation '

    # Inherit other CSV convertion parameters
    if ( $UseCulture ) {
     $scriptCmdPipeline += ' -UseCulture '
    }
    if ( $Delimiter ) {
     $scriptCmdPipeline += " -Delimiter '$Delimiter' "
    } 

    # Skip the first line (the one with the property names) 
    $scriptCmdPipeline += ' | Foreach-Object {$start=$true}'
    $scriptCmdPipeline += '{if ($start) {$start=$false} else {$_}} '

    # Add file output
    $scriptCmdPipeline += " | Out-File -FilePath '$Path'"
    $scriptCmdPipeline += " -Encoding '$Encoding' -Append "

    if ($Force) {
     $scriptCmdPipeline += ' -Force'
    }
    if ($NoClobber) {
     $scriptCmdPipeline += ' -NoClobber'
    }   
   }
  }
 } 

 $scriptCmd = {& $wrappedCmd @PSBoundParameters }

 if ( $AppendMode ) {
  # redefine command line
  $scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
      $scriptCmdPipeline
    )
 } else {
  # execute Export-CSV as we got it because
  # either -Append is missing or file does not exist
  $scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
      [string]$scriptCmd
    )
 }
 # standard pipeline initialization
 $steppablePipeline = $scriptCmd.GetSteppablePipeline(
        $myInvocation.CommandOrigin)
 $steppablePipeline.Begin($PSCmdlet)

 } catch {
   throw
 }

}
process
{
  try {
      $steppablePipeline.Process($_)
  } catch {
      throw
  }
}
end
{
  try {
      $steppablePipeline.End()
  } catch {
      throw
  }
}

}