Skip to content

Commit

Permalink
main
Browse files Browse the repository at this point in the history
  • Loading branch information
sharpchen committed Nov 25, 2024
1 parent 6715edb commit d934c54
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 36 deletions.
14 changes: 14 additions & 0 deletions docs/document/Powershell/docs/File System/Units of Size.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Units of Size

Powershell has builtin suffix for some numeric types that can represent file size and memory size like `mb`, `gb` and so on.
Powershell recognized the units and convert it into the base representation of size which is `byte`.
So it's like some implicit operators in `C++` that do the job for us.

- **NOT** case-sensitive
- Auto converts into bytes(the default unit)
- No concrete or wrapper type exists, just a annotation.


```ps1
gci | where { $_.Length > 1kb }
```
102 changes: 102 additions & 0 deletions docs/document/Powershell/docs/Language/Array.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,110 @@

## Creation

```ps1
$foo = 1,2,3
$foo = @(1,2,3)
$foo = ,1 # with only one item
$foo = 1..10 # from inclusive range 1 to 10
$foo = @() # empty array
```

> [!NOTE]
> The default type of a array literal is `object[]`, you can annotate with a type.
> ```ps1
> [int[]]$foo = 1, 2, 3
> ```
> [!TIP]
> Prefer `,...` to create an array with single element, it has less ambiguity.
> [!NOTE]
> Things like `1,2,3` itself is an expression, you can capture them as an object.
> But it cannot spread out items except a weird `,(1,2,3)`.
>```ps1
>(1,2,3).Length # 3
>
>(,(1,2,3)).Length # 3 # does spread items # [!code highlight]
>
>(,@(1,2,3)).Length # 1 # does not spread items # [!code highlight]
>
>((gci), (gci ..)).Length # 2 # [!code highlight]
> ```
### Collect from Expressions
`@()` actually collects from expressions, and all items from expressions will be flattened into a whole array.
So it can be another way to spread out arrays into one.
- Use `;` to separate expressions for flatten arrays from them.
- Use `,` to separate expressions if you want them to be sub-array.
```ps1
@((1, 2, 3), (1, 2, 3)).Length # 2
@((1, 2, 3); (1, 2, 3)).Length # 6
@((ls), (ls ..)).Length # 2
@(ls; ls ..).Length # > 0
```
## Access an Item

Powershell allows

## Concatenation

Generates new array from two concatenated.

```ps1
((1,2,3) + (1,2,3)).Length # 6
```

## Repetition

Use `*` to repeat the array content for certain times.

```ps1
((1,2,3) * 3).Length # 9
```

## Slicing

Use range operator to slice an array.

```ps1
(1..10)[0..5] # 1 to 6
(1..10)[-3..-1] # 8 to 10, last 3 items
# Reversed slicing
(1..10)[-1..-3] # 10, 9, 8; last 3 items in a reversed order
((1..10)[-1..-1]) -is [Array] # True, slicing always returns array
```

> [!NOTE]
> Differ from `C#`, range operator in Powershell is inclusive from both sides.
### Range Unions

You can specify multiple ranges for slicing with `+`, selected item will be collected together.
Separate different ranges by `+` to generate a range union.

> [!NOTE]
> A range can be a single index or simple range
```ps1
# Select 1 to 3, 5 to 6, and a single 8
(1..10)[0..2+4..5+7]
```

## Multi-Dim Array

You'll have to create Multi-Dim array from .NET type constructor only.

```ps1
$foo = [int[,]]::New(2, 2) # 2 * 2 array
```
5 changes: 0 additions & 5 deletions docs/document/Powershell/docs/Language/Collection.md

This file was deleted.

15 changes: 15 additions & 0 deletions docs/document/Powershell/docs/Language/Control Flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Control Flow

## Falsy Values

- `$false`
- `$null`
- Empty string
- Numeric zeros
- Empty collections implemented `IList`.

> [!NOTE]
> You can cast falsy values to boolean.
>```ps1
>[bool]@() # False
>```
10 changes: 10 additions & 0 deletions docs/document/Powershell/docs/Language/HashTable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# HashTable

## Merging

```ps1
@{ foo = 123; bar = '123' } + @{ baz = 234 }
```

> [!WARNING]
> `+` will throw if the two have any duplicated key.
2 changes: 2 additions & 0 deletions docs/document/Powershell/docs/Language/Keyword Operators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Keyword Operators

9 changes: 0 additions & 9 deletions docs/document/Powershell/docs/Language/Operators.md

This file was deleted.

20 changes: 20 additions & 0 deletions docs/document/Powershell/docs/Language/Scope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Scope

Variables and functions can have a explicit scope.

```ps1
$<scope>:foo = 1
function <scope>:Foo {}
```

## Scope Modifier

- `global`: accessible for the whole session. The root parent scope in a runspace.
- `local`: default. Accessible in current script or script block or function. Can be accessed by child scopes.
- `private`: accessible for current scope, meaning it can't be accessed by any other scope.
- `script`: only accessible in script module. The default scope in a
- Scopes from PSProviders
- `env`: environment variables
- `alias`: alias
- `function`
- `variable`
12 changes: 8 additions & 4 deletions docs/document/Powershell/docs/Language/String.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ Use `@'...'@` or `@"..."@` to present Verbatim Here String or Interpolated Here
> [!NOTE]
> You can have quotation mark `"` in `@"..."@` and for `'` respectively.
## String Concatenation

Use `+`

## Character Escaping

### Quotation Mark
Expand Down Expand Up @@ -99,6 +95,14 @@ Use double `'` to escape `'` in a verbatim string.

## Format String

## Repetition

Use `*` to repeat a string.

```ps1
'abc' * 2 # abcabc
```

## String Evaluation in Interpolation

### Collection
Expand Down
2 changes: 2 additions & 0 deletions docs/document/Powershell/docs/Language/Variable.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ echo $var
```

## Scope


Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
# Object Members

## Member Inspection

> [!TIP]
> Use `gm` alias for `Get-Member`.
```ps1
ls | Get-Member
```

When inspecting an array of objects, `gm` only returns members for distinct types.

```ps1
@(123, '123') | gm | select -ExpandProperty TypeName -Unique
# System.Int32
# System.String
(@('123', 123) | Get-Member).Length # 82
(@('123', 123, 123) | Get-Member).Length # still 82
```

`Get-Member` returns a `MemberDefinition[]` or a `MemberDefinition` with following properties.

```cs
Expand Down
26 changes: 18 additions & 8 deletions docs/document/Powershell/docs/Object Manipulation/Select.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ gps | select -ExpandProperty Name
> `Foreach-Object` can achieve the same thing
> ```ps1
> gps | foreach Name
> # or use another alias of Foreach-Object %
> # or use another alias of ForEach-Object %
> gps | % Name
> ```
Expand All @@ -93,16 +93,26 @@ gps | select -ExpandProperty Name
> This approach mutates the selected property instead of generating a new object.
```ps1
$john = @{
Name = 'John Smith'
Age = 30
Pet = @{
Name = 'Max'
Age = 6
$player = @{
Id = 123
Level = 15
Status = 'Empowered'
Partner = @{
Id = 234
Level = 12
Status = 'Poisoned'
}
}
$john | select Name, Age -ExpandProperty Pet
# Adds a NoteProperty `Status` with the same value from $player to $player.Partner
$partner = $john | select Status -ExpandProperty Partner
[object]::ReferenceEquals($partner, $john.Child) # True
$child | gm -MemberType NoteProperty # Status
$partner.Status # Empowered # . accessor prefers ETS property
$partner['Status'] # Poisoned
```
> [!NOTE]
Expand Down
10 changes: 0 additions & 10 deletions docs/document/Powershell/docs/Terminology & Naming.md

This file was deleted.

25 changes: 25 additions & 0 deletions docs/document/Powershell/docs/Terminology.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Terminology

Powershell has its own terminologies besides other shells like bash.
It's a shell integrated with .NET, it's not a independent platform.

- `cmdlet`: builtin utils inside powershell, implemented using other languages like `C#`.
- `function`: a command implemented using powershell language itself.
- `application`: external executable.

## Session

Session is an environment state created on Powershell instance starts.
A session is not a scope, all environment of sessions are isolated.
The scope of the session is the top scope.

## Runspace

Runspace is a customized instance of Powershell by powershell code.
In general, you can't control how powershell loads Providers and builtin member and so on.
So Powershell exposes such api to create a customized object to represent the truncated or enhanced instance of the Powershell environment.
By this approach, you can expose minimal privileges and custom utilities to users for certain tasks.

Each Runspace creates isolated session state just like a normal powershell instance.

A normal powershell can be referred as a Runspace too.
31 changes: 31 additions & 0 deletions docs/document/Powershell/docs/Understanding Pipeline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#

Overview of pipeline in powershell:

- A cmdlet can have multiple parameters that accept pipeline input.
- Only one parameter can bind to a given pipeline object at a time.
- PowerShell prioritizes by value over by property name.

## Pipeline Parameter Binding


## How Cmdlet Accept a Pipeline Input

There's two solution when a pipeline input comes in as a fallback:

- ByValue: accepts when the coming object can be cast to the target type of the parameter.
- ByPropertyName: accepts when the coming object has property name matched to any parameter name of the cmdlet.


```ps1
spps -Name (gci -File | foreach Name)
# is equivalent to
# because FileInfo has Name which matches to -Name parameter of spps cmdlet
gci -File | spps
```

> [!WARNING]
> If multiple matches exist on ByPropertyName solution, powershell throws an error since these paramters might not be allowed to be used together.
By value is always tried first, and then use ByPropertyName, or it finally throws.
A parameter accepts pipeline input does not necessarily have both solutions, it can have at least one of them.

0 comments on commit d934c54

Please sign in to comment.