PowerShell 7.x - قسمت پنجم - اسکریپت بلاک و توابع
نویسنده: سیروان عفیفی
تاریخ: ۱۴۰۱/۰۸/۱۴ ۰:۳۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
Get-Process | Where-Object { $_.Name -eq 'Dropbox' } PS /Users/sirwanafifi/Desktop> $block = {
>> $newVar = 10
>> Write-Host $newVar
>> } PS /Users/sirwanafifi/Desktop> & $block
PS /Users/sirwanafifi/Desktop> & "Get-Process"
PS /Users/sirwanafifi/Desktop> & "1 + 1" or PS /Users/sirwanafifi/Desktop> & "Get-Process -Name Slack"
Function Add-Something {
Write-Host "$_ World"
}
"Hello" | Add-Something Function Add-Something {
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline = $true)]
[string]$Name
)
Write-Host "$Name World"
}
"Hello" | Add-Something $API_KEY = "...."
Function Read-WeatherData {
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline = $true)]
[string]$CityName
)
$Url = "https://api.openweathermap.org/data/2.5/forecast?q=$CityName&cnt=40&appid=$API_KEY&units=metric"
Try {
Write-Verbose "Reading weather data for $CityName"
$Response = Invoke-RestMethod -Uri $Url
$Response.list | ForEach-Object {
Write-Verbose "Processing $($_.dt_txt)"
[PSCustomObject]@{
City = $Response.city.name
DateTime = [DateTime]::Parse($_.dt_txt)
Temperature = $_.main.temp
Humidity = $_.main.humidity
Pressure = $_.main.pressure
WindSpeed = $_.wind.speed
WindDirection = $_.wind.deg
Cloudiness = $_.clouds.all
Weather = $_.weather.main
WeatherDescription = $_.weather.description
}
} | Where-Object { $_.DateTime.Date -eq (Get-Date).Date }
Write-Verbose "Done processing $CityName"
}
Catch {
Write-Error $_.Exception.Message
}
} Read-WeatherData -CityName "London" -Verbose
PS /> [Parameter]::new() ExperimentName : ExperimentAction : None Position : -2147483648 ParameterSetName : __AllParameterSets Mandatory : False ValueFromPipeline : False ValueFromPipelineByPropertyName : False ValueFromRemainingArguments : False HelpMessage : HelpMessageBaseName : HelpMessageResourceId : DontShow : False TypeId : System.Management.Automation.ParameterAttribute
Function Ping-Website {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[ValidatePattern('^www\..*')]
[string[]]$Websites,
[ValidateRange(1, 3)]
[int]$Count = 3
)
$Results = @()
$Websites | ForEach-Object {
$Website = $_
$Result = Test-Connection -ComputerName $Website -Count $Count -Quiet
$ResultText = $Result ? 'Success' : 'Failed'
$Results += @{
Website = $Website
Result = $ResultText
}
Write-Verbose "The result of pinging $Website is $ResultText"
}
$Results | ForEach-Object {
$_ | Select-Object @{ Name = "Website"; Expression = { $_.Website }; }, @{ Name = "Result"; Expression = { $_.Result }; }, @{ Name = "Number Of Attempts"; Expression = { $Count }; }
}
} Function Ping-Website {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[ValidateScript({
If (-Not ($_ | Test-Path) ) {
Throw "File or folder does not exist"
}
If (-Not ($_ | Test-Path -PathType Leaf) ) {
Throw "The Path argument must be a file. Folder paths are not allowed."
}
If ($_ -NotMatch "(\.json)$") {
throw "The file specified in the path argument must be either of type json"
}
Return $true
})]
[Alias("src", "source", "file")]
[System.IO.FileInfo]$Path,
[int]$Count = 1
)
$Results = [System.Collections.ArrayList]@()
$Urls = Get-Content -Path $Path | ConvertFrom-Json
$Urls | ForEach-Object -Parallel {
$Website = $_.url
$Result = Test-Connection -ComputerName $Website -Count $using:Count -Quiet
$ResultText = $Result ? 'Success' : 'Failed'
$Item = @{
Website = $Website
Result = $ResultText
}
$null = ($using:Results).Add($Item)
}
$Results | ForEach-Object -Parallel {
$_ | Select-Object @{ Name = "Website"; Expression = { $_.Website }; }, @{ Name = "Result"; Expression = { $_.Result }; }, @{ Name = "Number Of Attempts"; Expression = { $using:Count }; }
}
} Function Ping-Website {
[CmdletBinding()]
Param(
# As before
)
# As before
$Urls | ForEach-Object -Parallel {
$DebugPreference = $using:DebugPreference
$VerbosePreference = $using:VerbosePreference
$InformationPreference = $using:InformationPreference
# As before
}
# As before
} $scriptBlock = {
$logOutput = {
param($message)
Write-Host $message
}
[int]$someVariable = 10
$doSomeWork = {
& $logOutput -message "Some variable value: $someVariable"
}
$someVariable = 20
& $doSomeWork
} $scriptBlock = {
$logOutput = {
param($message)
Write-Host $message
}
[int]$someVariable = 10
$doSomeWork = {
& $logOutput -message "Some variable value: $someVariable"
}.GetNewClosure()
$someVariable = 20
& $doSomeWork
} begin process end dynamicparam
function Show-Pipeline {
begin {
Write-Host "Pipeline start"
}
process {
Write-Host "Pipeline process $_"
}
end {
Write-Host "Pipeline end $_"
}
} PS /> 1..2 | Show-Pipeline Pipeline start Pipeline process 1 Pipeline process 2 Pipeline end 2
PS /> "www.google.com", "www.yahoo.com" | Ping-Website Website Result Number Of Attempts ------- ------ ------------------ www.yahoo.com Success 3
Function Ping-Website {
[CmdletBinding()]
Param(
# As before
)
process {
# As before
}
} PS /> "www.google.com", "www.yahoo.com" | Ping-Website Website Result Number Of Attempts ------- ------ ------------------ www.google.com Success 3 www.yahoo.com Success 3
PS /> Read-Csv ./users.csv -Columns name
using namespace System.Management.Automation
Function Read-Csv {
Param (
[Parameter(Mandatory = $true, Position = 0)]
[string]$Path
)
DynamicParam {
$firstLine = Get-Content $Path | Select-Object -First 1
[String[]]$headers = $firstLine -split ', '
$parameters = [RuntimeDefinedParameterDictionary]::new()
$parameter = [RuntimeDefinedParameter]::new(
'Columns', [String[]], [Attribute[]]@(
[Parameter]@{ Mandatory = $false; Position = 1 }
[ValidateSet]::new($headers)
)
)
$parameters.Add($parameter.Name, $parameter)
Return $parameters
}
Begin {
$csvContent = Import-Csv $Path
If ($PSBoundParameters.ContainsKey('Columns')) {
$columns = $PSBoundParameters['Columns']
$csvContent | Select-Object -Property $columns
}
Else {
$csvContent
}
}
}
using namespace System.Net.NetworkInformation
## Pinging a remote system
function Get-PingReply {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[Alias('IPAddress', 'Destination')]
[string] $Target
)
begin {
$Ping = [Ping]::new()
# Timeout is in ms
$Timeout = 2500
[byte[]] $Buffer = 1..32
# 128 TTL and avoid fragmentation
$PingOptions = [PingOptions]::new(128, $true)
}
process {
$Ping.Send($Target, $Timeout, $Buffer, $PingOptions)
}
clean {
if ($Ping) { $Ping.Dispose() }
}
}
'1.2.3.4', 'www.google.com', '8.8.8.8' | Get-PingReply