Initial commit

parents
Showing with 4835 additions and 0 deletions
##############################################################################
##
## Add-ExtendedFileProperties
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Add the extended file properties normally shown in Exlorer's
"File Properties" tab.
.EXAMPLE
PS > Get-ChildItem | Add-ExtendedFileProperties.ps1 | Format-Table Name,"Bit Rate"
#>
begin
{
Set-StrictMode -Version 3
## Create the Shell.Application COM object that provides this
## functionality
$shellObject = New-Object -Com Shell.Application
## Remember the column property mappings
$columnMappings = @{}
}
process
{
## Store the property names and identifiers for all of the shell
## properties
$itemProperties = @{}
## Get the file from the input pipeline. If it is just a filename
## (rather than a real file,) piping it to the Get-Item cmdlet will
## get the file it represents.
$fileItem = $_ | Get-Item
## Don't process directories
if($fileItem.PsIsContainer)
{
$fileItem
return
}
## Extract the file name and directory name
$directoryName = $fileItem.DirectoryName
$filename = $fileItem.Name
## Create the folder object and shell item from the COM object
$folderObject = $shellObject.NameSpace($directoryName)
$item = $folderObject.ParseName($filename)
## Populate the item properties
$counter = 0
$columnName = ""
do
{
if(-not $columnMappings[$counter])
{
$columnMappings[$counter] = $folderObject.GetDetailsOf(
$folderObject.Items, $counter)
}
$columnName = $columnMappings[$counter]
if($columnName)
{
$itemProperties[$columnName] =
$folderObject.GetDetailsOf($item, $counter)
}
$counter++
} while($columnName)
## Process extended properties
foreach($name in
$item.ExtendedProperty('System.PropList.FullDetails').Split(';'))
{
$name = $name.Replace("*","")
$itemProperties[$name] = $item.ExtendedProperty($name)
}
## Now, go through each property and add its information as a
## property to the file we are about to return
foreach($itemProperty in $itemProperties.Keys)
{
$value = $itemProperties[$itemProperty]
if($value)
{
$fileItem | Add-Member NoteProperty $itemProperty `
$value -ErrorAction `
SilentlyContinue
}
}
## Finally, return the file with the extra shell information
$fileItem
}
\ No newline at end of file
##############################################################################
##
## Add-FormatData
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Adds a table formatting definition for the specified type name.
.EXAMPLE
PS > $r = [PSCustomObject] @{
Name = "Lee";
Phone = "555-1212";
SSN = "123-12-1212"
}
PS > $r.PSTypeNames.Add("AddressRecord")
PS > Add-FormatData -TypeName AddressRecord -TableColumns Name, Phone
PS > $r
Name Phone
---- -----
Lee 555-1212
#>
param(
## The type name (or PSTypeName) that the table definition should
## apply to.
$TypeName,
## The columns to be displayed by default
[string[]] $TableColumns
)
Set-StrictMode -Version 3
## Define the columns within a table control row
$rowDefinition = New-Object Management.Automation.TableControlRow
## Create left-aligned columns for each provided column name
foreach($column in $TableColumns)
{
$rowDefinition.Columns.Add(
(New-Object Management.Automation.TableControlColumn "Left",
(New-Object Management.Automation.DisplayEntry $column,"Property")))
}
$tableControl = New-Object Management.Automation.TableControl
$tableControl.Rows.Add($rowDefinition)
## And then assign the table control to a new format view,
## which we then add to an extended type definition. Define this view for the
## supplied custom type name.
$formatViewDefinition = New-Object Management.Automation.FormatViewDefinition "TableView",$tableControl
$extendedTypeDefinition = New-Object Management.Automation.ExtendedTypeDefinition $TypeName
$extendedTypeDefinition.FormatViewDefinition.Add($formatViewDefinition)
## Add the definition to the session, and refresh the format data
[Runspace]::DefaultRunspace.InitialSessionState.Formats.Add($extendedTypeDefinition)
Update-FormatData
\ No newline at end of file
##############################################################################
##
## Add-FormatTableIndexParameter
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Adds a new -IncludeIndex switch parameter to the Format-Table command
to help with array indexing.
.NOTES
This commands builds on New-CommandWrapper, also included in the Windows
PowerShell Cookbook.
.EXAMPLE
PS > $items = dir
PS > $items | Format-Table -IncludeIndex
PS > $items[4]
#>
Set-StrictMode -Version 3
New-CommandWrapper Format-Table `
-AddParameter @{
@{
Name = 'IncludeIndex';
Attributes = "[Switch]"
} = {
function Add-IndexParameter {
begin
{
$psIndex = 0
}
process
{
## If this is the Format-Table header
if($_.GetType().FullName -eq `
"Microsoft.PowerShell.Commands.Internal." +
"Format.FormatStartData")
{
## Take the first column and create a copy of it
$formatStartType =
$_.shapeInfo.tableColumnInfoList[0].GetType()
$clone =
$formatStartType.GetConstructors()[0].Invoke($null)
## Add a PSIndex property
$clone.PropertyName = "PSIndex"
$clone.Width = $clone.PropertyName.Length
## And add its information to the header information
$_.shapeInfo.tableColumnInfoList.Insert(0, $clone)
}
## If this is a Format-Table entry
if($_.GetType().FullName -eq `
"Microsoft.PowerShell.Commands.Internal." +
"Format.FormatEntryData")
{
## Take the first property and create a copy of it
$firstField =
$_.formatEntryInfo.formatPropertyFieldList[0]
$formatFieldType = $firstField.GetType()
$clone =
$formatFieldType.GetConstructors()[0].Invoke($null)
## Set the PSIndex property value
$clone.PropertyValue = $psIndex
$psIndex++
## And add its information to the entry information
$_.formatEntryInfo.formatPropertyFieldList.Insert(
0, $clone)
}
$_
}
}
$newPipeline = { __ORIGINAL_COMMAND__ | Add-IndexParameter }
}
}
\ No newline at end of file
##############################################################################
##
## Add-ObjectCollector
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Adds a new Out-Default command wrapper to store up to 500 elements from
the previous command. This wrapper stores output in the $ll variable.
.EXAMPLE
PS > Get-Command $pshome\powershell.exe
CommandType Name Definition
----------- ---- ----------
Application powershell.exe C:\Windows\System32\Windo...
PS > $ll.Definition
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
.NOTES
This command builds on New-CommandWrapper, also included in the Windows
PowerShell Cookbook.
#>
Set-StrictMode -Version 3
New-CommandWrapper Out-Default `
-Begin {
$cachedOutput = New-Object System.Collections.ArrayList
} `
-Process {
## If we get an input object, add it to our list of objects
if($_ -ne $null) { $null = $cachedOutput.Add($_) }
while($cachedOutput.Count -gt 500) { $cachedOutput.RemoveAt(0) }
} `
-End {
## Be sure we got objects that were not just errors (
## so that we don't wipe out the saved output when we get errors
## trying to work with it.)
## Also don't caputre formatting information, as those objects
## can't be worked with.
$uniqueOutput = $cachedOutput | Foreach-Object {
$_.GetType().FullName } | Select -Unique
$containsInterestingTypes = ($uniqueOutput -notcontains `
"System.Management.Automation.ErrorRecord") -and
($uniqueOutput -notlike `
"Microsoft.PowerShell.Commands.Internal.Format.*")
## If we actually had output, and it was interesting information,
## save the output into the $ll variable
if(($cachedOutput.Count -gt 0) -and $containsInterestingTypes)
{
$GLOBAL:ll = $cachedOutput | % { $_ }
}
}
\ No newline at end of file
##############################################################################
##
## Add-RelativePathCapture
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Adds a new CommandNotFound handler that captures relative path
navigation without having to explicitly call 'Set-Location'
.EXAMPLE
PS C:\Users\Lee\Documents>..
PS C:\Users\Lee>...
PS C:\>
#>
Set-StrictMode -Version 3
$executionContext.SessionState.InvokeCommand.CommandNotFoundAction = {
param($CommandName, $CommandLookupEventArgs)
## If the command is only dots
if($CommandName -match '^\.+$')
{
## Associate a new command that should be invoked instead
$CommandLookupEventArgs.CommandScriptBlock = {
## Count the number of dots, and run "Set-Location .." one
## less time.
for($counter = 0; $counter -lt $CommandName.Length - 1; $counter++)
{
Set-Location ..
}
## We call GetNewClosure() so that the reference to $CommandName can
## be used in the new command.
}.GetNewClosure()
## Stop going through the command resolution process. This isn't
## strictly required in the CommandNotFoundAction.
$CommandLookupEventArgs.StopSearch = $true
}
}
\ No newline at end of file
##############################################################################
##
## Compare-Property
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Compare the property you provide against the input supplied to the script.
This provides the functionality of simple Where-Object comparisons without
the syntax required for that cmdlet.
.EXAMPLE
PS Get-Process | Compare-Property Handles gt 1000
.EXAMPLE
PS > Set-Alias ?? Compare-Property
PS > dir | ?? PsIsContainer
#>
param(
## The property to compare
$Property,
## The operator to use in the comparison
$Operator = "eq",
## The value to compare with
$MatchText = "$true"
)
Begin { $expression = "`$_.$property -$operator `"$matchText`"" }
Process { if(Invoke-Expression $expression) { $_ } }
\ No newline at end of file
##############################################################################
##
## Connect-WebService
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
## Connect to a given web service, and create a type that allows you to
## interact with that web service. In PowerShell version two, use the
## New-WebserviceProxy cmdlet.
##
## Example:
##
## $wsdl = "http://www.terraserver-usa.com/TerraService2.asmx?WSDL"
## $terraServer = Connect-WebService $wsdl
## $place = New-Object Place
## $place.City = "Redmond"
## $place.State = "WA"
## $place.Country = "USA"
## $facts = $terraserver.GetPlaceFacts($place)
## $facts.Center
##
##############################################################################
param(
## The URL that contains the WSDL
[string] $WsdlLocation = $(throw "Please specify a WSDL location"),
## The namespace to use to contain the web service proxy
[string] $Namespace,
## Switch to identify web services that require authentication
[Switch] $RequiresAuthentication
)
## Create the web service cache, if it doesn't already exist
if(-not (Test-Path Variable:\Lee.Holmes.WebServiceCache))
{
${GLOBAL:Lee.Holmes.WebServiceCache} = @{}
}
## Check if there was an instance from a previous connection to
## this web service. If so, return that instead.
$oldInstance = ${GLOBAL:Lee.Holmes.WebServiceCache}[$wsdlLocation]
if($oldInstance)
{
$oldInstance
return
}
## Load the required Web Services DLL
$null = [Reflection.Assembly]::LoadWithPartialName("System.Web.Services")
## Download the WSDL for the service, and create a service description from
## it.
$wc = New-Object System.Net.WebClient
if($requiresAuthentication)
{
$wc.UseDefaultCredentials = $true
}
$wsdlStream = $wc.OpenRead($wsdlLocation)
## Ensure that we were able to fetch the WSDL
if(-not (Test-Path Variable:\wsdlStream))
{
return
}
$serviceDescription =
[Web.Services.Description.ServiceDescription]::Read($wsdlStream)
$wsdlStream.Close()
## Ensure that we were able to read the WSDL into a service description
if(-not (Test-Path Variable:\serviceDescription))
{
return
}
## Import the web service into a CodeDom
$serviceNamespace = New-Object System.CodeDom.CodeNamespace
if($namespace)
{
$serviceNamespace.Name = $namespace
}
$codeCompileUnit = New-Object System.CodeDom.CodeCompileUnit
$serviceDescriptionImporter =
New-Object Web.Services.Description.ServiceDescriptionImporter
$serviceDescriptionImporter.AddServiceDescription(
$serviceDescription, $null, $null)
[void] $codeCompileUnit.Namespaces.Add($serviceNamespace)
[void] $serviceDescriptionImporter.Import(
$serviceNamespace, $codeCompileUnit)
## Generate the code from that CodeDom into a string
$generatedCode = New-Object Text.StringBuilder
$stringWriter = New-Object IO.StringWriter $generatedCode
$provider = New-Object Microsoft.CSharp.CSharpCodeProvider
$provider.GenerateCodeFromCompileUnit($codeCompileUnit, $stringWriter, $null)
## Compile the source code.
$references = @("System.dll", "System.Web.Services.dll", "System.Xml.dll")
$compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters
$compilerParameters.ReferencedAssemblies.AddRange($references)
$compilerParameters.GenerateInMemory = $true
$compilerResults =
$provider.CompileAssemblyFromSource($compilerParameters, $generatedCode)
## Write any errors if generated.
if($compilerResults.Errors.Count -gt 0)
{
$errorLines = ""
foreach($error in $compilerResults.Errors)
{
$errorLines += "`n`t" + $error.Line + ":`t" + $error.ErrorText
}
Write-Error $errorLines
return
}
## There were no errors. Create the webservice object and return it.
else
{
## Get the assembly that we just compiled
$assembly = $compilerResults.CompiledAssembly
## Find the type that had the WebServiceBindingAttribute.
## There may be other "helper types" in this file, but they will
## not have this attribute
$type = $assembly.GetTypes() |
Where-Object { $_.GetCustomAttributes(
[System.Web.Services.WebServiceBindingAttribute], $false) }
if(-not $type)
{
Write-Error "Could not generate web service proxy."
return
}
## Create an instance of the type, store it in the cache,
## and return it to the user.
$instance = $assembly.CreateInstance($type)
## Many services that support authentication also require it on the
## resulting objects
if($requiresAuthentication)
{
if(@($instance.PsObject.Properties |
where { $_.Name -eq "UseDefaultCredentials" }).Count -eq 1)
{
$instance.UseDefaultCredentials = $true
}
}
${GLOBAL:Lee.Holmes.WebServiceCache}[$wsdlLocation] = $instance
$instance
}
\ No newline at end of file
##############################################################################
##
## Convert-TextObject
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Convert a simple string into a custom PowerShell object.
.EXAMPLE
PS > "Hello World" | Convert-TextObject
Generates an Object with "P1=Hello" and "P2=World"
.EXAMPLE
PS > "Hello World" | Convert-TextObject -Delimiter "ll"
Generates an Object with "P1=He" and "P2=o World"
.EXAMPLE
PS > "Hello World" | Convert-TextObject -Pattern "He(ll.*o)r(ld)"
Generates an Object with "P1=llo Wo" and "P2=ld"
.EXAMPLE
PS > "Hello World" | Convert-TextObject -PropertyName FirstWord,SecondWord
Generates an Object with "FirstWord=Hello" and "SecondWord=World
.EXAMPLE
PS > "123 456" | Convert-TextObject -PropertyType $([string],[int])
Generates an Object with "Property1=123" and "Property2=456"
The second property is an integer, as opposed to a string
.EXAMPLE
PS > $ipAddress = (ipconfig | Convert-TextObject -Delim ": ")[2].P2
PS > $ipAddress
192.168.1.104
#>
[CmdletBinding(DefaultParameterSetName = "ByDelimiter")]
param(
## If specified, gives the .NET Regular Expression with which to
## split the string. The script generates properties for the
## resulting object out of the elements resulting from this split.
## If not specified, defaults to splitting on the maximum amount
## of whitespace: "\s+", as long as Pattern is not
## specified either.
[Parameter(ParameterSetName = "ByDelimiter", Position = 0)]
[string] $Delimiter = "\s+",
## If specified, gives the .NET Regular Expression with which to
## parse the string. The script generates properties for the
## resulting object out of the groups captured by this regular
## expression.
[Parameter(Mandatory = $true,
ParameterSetName = "ByPattern",
Position = 0)]
[string] $Pattern,
## If specified, the script will pair the names from this object
## definition with the elements from the parsed string. If not
## specified (or the generated object contains more properties
## than you specify,) the script uses property names in the
## pattern of P1,P2,...,PN
[Parameter(Position = 1)]
[Alias("PN")]
[string[]] $PropertyName = @(),
## If specified, the script will pair the types from this list with
## the properties from the parsed string. If not specified (or the
## generated object contains more properties than you specify,) the
## script sets the properties to be of type [string]
[Parameter(Position = 2)]
[Alias("PT")]
[type[]] $PropertyType = @(),
## The input object to process
[Parameter(ValueFromPipeline = $true)]
[string] $InputObject
)
begin {
Set-StrictMode -Version 3
}
process {
$returnObject = New-Object PSObject
$matches = $null
$matchCount = 0
if($PSBoundParameters["Pattern"])
{
## Verify that the input contains the pattern
## Populates the matches variable by default
if(-not ($InputObject -match $pattern))
{
return
}
$matchCount = $matches.Count
$startIndex = 1
}
else
{
## Verify that the input contains the delimiter
if(-not ($InputObject -match $delimiter))
{
return
}
## If so, split the input on that delimiter
$matches = $InputObject -split $delimiter
$matchCount = $matches.Length
$startIndex = 0
}
## Go through all of the matches, and add them as notes to the output
## object.
for($counter = $startIndex; $counter -lt $matchCount; $counter++)
{
$currentPropertyName = "P$($counter - $startIndex + 1)"
$currentPropertyType = [string]
## Get the property name
if($counter -lt $propertyName.Length)
{
if($propertyName[$counter])
{
$currentPropertyName = $propertyName[$counter - 1]
}
}
## Get the property value
if($counter -lt $propertyType.Length)
{
if($propertyType[$counter])
{
$currentPropertyType = $propertyType[$counter - 1]
}
}
Add-Member -InputObject $returnObject NoteProperty `
-Name $currentPropertyName `
-Value ($matches[$counter].Trim() -as $currentPropertyType)
}
$returnObject
}
\ No newline at end of file
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
param([double] $Fahrenheit)
Set-StrictMode -Version 3
## Convert Fahrenheit to Celsius
function ConvertFahrenheitToCelsius([double] $fahrenheit)
{
$celsius = $fahrenheit - 32
$celsius = $celsius / 1.8
$celsius
}
$celsius = ConvertFahrenheitToCelsius $fahrenheit
## Output the answer
"$fahrenheit degrees Fahrenheit is $celsius degrees Celsius."
\ No newline at end of file
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
param([double] $Fahrenheit)
Set-StrictMode -Version 3
## Convert it to Celsius
$celsius = $fahrenheit - 32
$celsius = $celsius / 1.8
## Output the answer
"$fahrenheit degrees Fahrenheit is $celsius degrees Celsius."
\ No newline at end of file
##############################################################################
##
## Copy-History
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Copy selected commands from the history buffer into the clipboard as a script.
.EXAMPLE
PS > Copy-History
Copies the entire contents of the history buffer into the clipboard.
.EXAMPLE
PS > Copy-History -5
Copies the last five commands into the clipboard.
.EXAMPLE
PS > Copy-History 2,5,8,4
Copies commands 2,5,8, and 4.
.EXAMPLE
PS > Copy-History (1..10+5+6)
Copies commands 1 through 10, then 5, then 6, using PowerShell's array
slicing syntax.
#>
param(
## The range of history IDs to copy
[int[]] $Range
)
Set-StrictMode -Version 3
$history = @()
## If they haven't specified a range, assume it's everything
if((-not $range) -or ($range.Count -eq 0))
{
$history = @(Get-History -Count ([Int16]::MaxValue))
}
## If it's a negative number, copy only that many
elseif(($range.Count -eq 1) -and ($range[0] -lt 0))
{
$count = [Math]::Abs($range[0])
$history = (Get-History -Count $count)
}
## Otherwise, go through each history ID in the given range
## and add it to our history list.
else
{
foreach($commandId in $range)
{
if($commandId -eq -1) { $history += Get-History -Count 1 }
else { $history += Get-History -Id $commandId }
}
}
## Finally, export the history to the clipboard.
$history | Foreach-Object { $_.CommandLine } | clip.exe
\ No newline at end of file
#############################################################################
##
## Enable-BreakOnError
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Creates a breakpoint that only fires when PowerShell encounters an error
.EXAMPLE
PS > Enable-BreakOnError
ID Script Line Command Variable Action
-- ------ ---- ------- -------- ------
0 Out-Default ...
PS > 1/0
Entering debug mode. Use h or ? for help.
Hit Command breakpoint on 'Out-Default'
PS > $error
Attempted to divide by zero.
#>
Set-StrictMode -Version 3
## Store the current number of errors seen in the session so far
$GLOBAL:EnableBreakOnErrorLastErrorCount = $error.Count
Set-PSBreakpoint -Command Out-Default -Action {
## If we're generating output, and the error count has increased,
## break into the debugger.
if($error.Count -ne $EnableBreakOnErrorLastErrorCount)
{
$GLOBAL:EnableBreakOnErrorLastErrorCount = $error.Count
break
}
}
\ No newline at end of file
##############################################################################
##
## Enable-HistoryPersistence
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################