Skip to content

Commit

Permalink
v1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
TobiasPSP committed Nov 6, 2019
1 parent e860088 commit 2ddb294
Show file tree
Hide file tree
Showing 8 changed files with 464 additions and 0 deletions.
102 changes: 102 additions & 0 deletions PSOneTools/1.3/Foreach-ObjectFast.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
function Foreach-ObjectFast
{
<#
.SYNOPSIS
Faster Foreach-Object
.DESCRIPTION
Foreach-ObjectFast can replace the built-in Foreach-Object and improves pipeline speed considerably.
Foreach-ObjectFast supports only the most commonly used parameters -Begin, -Process, and -End, so you can replace
1..100 | Foreach-Object { 'Server{0:d3}' -f $_ }
with
1..100 | Foreach-ObjectFast { 'Server{0:d3}' -f $_ }
but you cannot currently replace instances of Foreach-Object that uses the less commonly used parameters,
like -RemainingScripts, -MemberNames, and -ArgumentList
Foreach-ObjectFast has a performance benefit per iteration, so the more objects
you send through the pipeline, the more significant performace benefits you will see.
Foreach-ObjectFast is using a steppable pipeline internally which performs better.
However because of this, the debugging experience will be different, and internal
variables such as $MyInvocation may yield different results. For most every-day tasks,
these changes are not important.
A complete explanation of what Where-ObjectFast does can be found here:
https://powershell.one/tricks/performance/pipeline
.EXAMPLE
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$result = 1..1000000 | Foreach-ObjectFast -Process {
"I am at $_"
}
$report = '{0} elements in {1:n2} seconds'
$report -f $result.Count, $stopwatch.Elapsed.TotalSeconds
Demos the speed improvements. Run this script to see how well it performs,
then replace Foreach-ObjectFast with the default Foreach-Object, and check out
the performace difference. $result is the same in both cases.
.LINK
https://powershell.one/tricks/performance/pipeline
https://github.com/TobiasPSP/Modules.PSOneTools/blob/master/PSOneTools/1.2/Foreach-ObjectFast.ps1
#>

param
(
# executes for each pipeline element
[ScriptBlock]
$Process,

# executes once before the pipeline is started.
# can be used for initialization routines
[ScriptBlock]
$Begin,

# executes once after all pipeline elements have been processed
# can be used to do cleanup work
[ScriptBlock]
$End
)

begin
{
# construct a hard-coded anonymous simple function from
# the submitted scriptblocks:
$code = @"
& {
begin
{
$Begin
}
process
{
$Process
}
end
{
$End
}
}
"@
# turn code into a scriptblock and invoke it
# via a steppable pipeline so we can feed in data
# as it comes in via the pipeline:
$pip = [ScriptBlock]::Create($code).GetSteppablePipeline($myInvocation.CommandOrigin)
$pip.Begin($true)
}
process
{
# forward incoming pipeline data to the custom scriptblock:
$pip.Process($_)
}
end
{
$pip.End()
}
}
Binary file added PSOneTools/1.3/PSOneTools.psd1
Binary file not shown.
60 changes: 60 additions & 0 deletions PSOneTools/1.3/Test-PSOnePing.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

function Test-PSOnePing
{
<#
.SYNOPSIS
Sends a ping (ICMP) to a computer
.DESCRIPTION
Sends a ping (ICMP) to a computer
.EXAMPLE
Test-PSOnePing -ComputerName 127.0.0.1, microsoft.com, powershell.one -Timeout 2000
Pings three computers with a maximum timeout of 2000 milliseconds
.EXAMPLE
'127.0.0.1', 'microsoft.com', 'powershell.one' | Test-PSOnePing -Timeout 2000
Pings three computers with a maximum timeout of 2000 milliseconds
.EXAMPLE
Get-ADComputer -Filter * | Select-Object -ExpandProperty Name | Test-PSOnePing -Timeout 2000
Pings all computers received from Get-ADComputer with a maximum timeout of 2000 milliseconds
Module "ActiveDirectory" required for Get-ADComputer
.LINK
https://powershell.one/tricks/network/ping
#>


param
(
# Computername or IP address to ping
[Parameter(Mandatory,ValueFromPipeline)]
[string[]]
$ComputerName,

# Timeout in milliseconds
[int]
[ValidateRange(100,50000)]
$Timeout = 2000
)

begin
{
$Online = @{
Name = 'Online'
Expression = { $_.Status -eq 'Success' }
}
$obj = New-Object System.Net.NetworkInformation.Ping
}

process
{
$ComputerName |
ForEach-Object {
$obj.Send($_, $timeout) |
Select-Object -Property $Online, Status, Address |
Add-Member -MemberType NoteProperty -Name Name -Value $_ -PassThru
}
}
}
126 changes: 126 additions & 0 deletions PSOneTools/1.3/Test-PSOnePort.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
function Test-PSOnePort
{
<#
.SYNOPSIS
Tests a network port on a remote computer
.DESCRIPTION
Tests whether a port on a remote computer is responding.
.EXAMPLE
Test-PSOnePort -ComputerName 127.0.0.1 -Port 4000 -Timeout 1000
Tests whether port 4000 on the local computer is responding,
and waits a maximum of 1000 milliseconds
.EXAMPLE
Test-PSOnePort -ComputerName 127.0.0.1 -Port 4000 -Timeout 1000 -Count 30 -Delay 2000
Tests 30 times whether port 4000 on the local computer is responding,
and waits a maximum of 1000 milliseconds inbetween each test
.EXAMPLE
Test-PSOnePort -ComputerName 127.0.0.1 -Port 4000 -Timeout 1000 -Count 0 -Delay 2000 -ExitOnSuccess
Continuously tests whether port 4000 on the local computer is responding,
waits a maximum of 1000 milliseconds inbetween each test,
and exits as soon as the port is responding
.LINK
https://powershell.one/tricks/network/porttest
#>


param
(
[Parameter(Mandatory)]
[string]
$ComputerName,

# port number to test
[Parameter(Mandatory)]
[int]
$Port,

# timeout in milliseconds
[int]
$Timeout = 500,

# number of tries. A value of 0 indicates countinuous testing
[int]
[ValidateRange(0,1000)]
$Count = 1,

# delay (in milliseconds) inbetween continuous tests
$Delay = 2000,

# when enabled, function returns as soon as port is available
[Switch]
$ExitOnSuccess
)
$ok = $false
$c = 0
$isOnline = $false
$continuous = $Count -eq 0 -or $Count -gt 1
try
{
do
{
$c++
if ($c -gt $Count -and !$continuous) {
# count exceeded
break
}
$start = Get-Date

$tcpobject = [system.Net.Sockets.TcpClient]::new()
$connect = $tcpobject.BeginConnect($computername,$port,$null,$null)
$wait = $connect.AsyncWaitHandle.WaitOne($timeout,$false)

if(!$wait) {
# no response from port
$tcpobject.Close()
$tcpobject.Dispose()

Write-Verbose "Port $Port is not responding..."
if ($continuous) { Write-Host '.' -NoNewline }
} else {
try {
# port is reachable
if ($continuous) { Write-Host '!' -NoNewline }
[void]$tcpobject.EndConnect($connect)
$tcpobject.Close()
$tcpobject.Dispose()

$isOnline = $true
if ($ExitOnSuccess)
{
$ok = $true
$delay = 0
}
}
catch {
# access to port restricted
throw "You do not have permission to contact port $Port."
}
}
$stop = Get-Date
$timeUsed = ($stop - $start).TotalMilliseconds
$currentDelay = $Delay - $timeUsed
if ($currentDelay -gt 100)
{
Start-Sleep -Milliseconds $currentDelay
}

} until ($ok)
}
finally
{
# dispose objects to free memory
if ($tcpobject)
{
$tcpobject.Close()
$tcpobject.Dispose()
}
}
if ($continuous) { Write-Host }

return $isOnline
}
66 changes: 66 additions & 0 deletions PSOneTools/1.3/Test-PSOneScript.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@


function Test-PSOneScript
{
<#
.SYNOPSIS
Parses a PowerShell Script (*.ps1, *.psm1, *.psd1)
.DESCRIPTION
Invokes the simple PSParser and returns tokens and syntax errors
.EXAMPLE
Test-PSOneScript -Path c:\test.ps1
Parses the content of c:\test.ps1 and returns tokens and syntax errors
.EXAMPLE
Get-ChildItem -Path $home -Recurse -Include *.ps1,*.psm1,*.psd1 -File |
Test-PSOneScript |
Out-GridView
parses all PowerShell files found anywhere in your user profile
.EXAMPLE
Get-ChildItem -Path $home -Recurse -Include *.ps1,*.psm1,*.psd1 -File |
Test-PSOneScript |
Where-Object Errors
parses all PowerShell files found anywhere in your user profile
and returns only those files that contain syntax errors
.LINK
https://powershell.one
#>


param
(
# Path to PowerShell script file
# can be a string or any object that has a "Path"
# or "FullName" property:
[String]
[Parameter(Mandatory,ValueFromPipeline)]
[Alias('FullName')]
$Path
)

begin
{
$errors = $null
}
process
{
# create a variable to receive syntax errors:
$errors = $null
# tokenize PowerShell code:
$code = Get-Content -Path $Path -Raw -Encoding Default

# return the results as a custom object
[PSCustomObject]@{
Name = Split-Path -Path $Path -Leaf
Path = $Path
Tokens = [Management.Automation.PSParser]::Tokenize($code, [ref]$errors)
Errors = $errors | Select-Object -ExpandProperty Token -Property Message
}
}
}
Loading

0 comments on commit 2ddb294

Please sign in to comment.