What is the difference between Set-Variable foo -Scope Global -Value "bar" and $global:foo = "bar"
I have seen that Set-Variable implements -WhatIf/-Confim so the assignment only happens if these are not set or the action is confirmed whereas the assignment happens regardless. Is there anything else lurking?
UPDATE
Following is an example of how the 2 are different in the presence of -Whatif / -Confirm:
Clear-Variable foo -ErrorAction:SilentlyContinue # just in case
Function repro {
[CmdletBinding(SupportsShouldProcess)] Param()
Set-Variable foo -Scope Global -Value "bar"
}
repro -WhatIf
Write-Host "`$global:foo=$($global:foo)"
You should see:
What if: Performing the operation "Set variable" on target "Name: foo Value: bar".
$global:foo=
However:
Clear-Variable foo -ErrorAction:SilentlyContinue # just in case
Function repro {
[CmdletBinding(SupportsShouldProcess)] Param()
$global:foo = "bar"
}
repro -WhatIf
Write-Host "`$global:foo=$($global:foo)"
Now you get:
$global:foo=bar
The difference isn't much but the Set-Variable
has a few more options available to it than just a regular assignment expression. It's just a matter of how verbose you want to be with your syntax and what you are trying to accomplish.
These are simple, quick variable assignments not much to it.
$foo = "bar"
# If you want to change scope, add it
$global:foo = "bar"
$script:foo = "bar"
Set-Variable
CmdLet As you've pointed out, the Set-Variable
Cmdlet has a few more options with it, like -WhatIf
and -Confirm
. It also has a few other options like setting the type of variable with -Option
and -PassThru
. -Option
allows for the setting of constants, readonly variables, or private scoped variables. -PassThru
is pretty useful to and I'll give an example below. A couple more parameters are also available to so review them here
# PassThru executes your Set-Variable and then continues to
# pass the variable through the pipeline so with it you can
# assign your variable and then immediately start working with it
Set-Variable -Name "FooArr" -Value @("bar", "baz", "boom") -PassThru | ForEach-Object {
$_.Value
}
$FooArr # Still assigned
bar
baz
boom
# Constant
Set-Variable -Name "ImAConstant" -Value "Try to delete me" -Option Constant
Remove-Variable -Name "ImAConstant"
# Error
Remove-Variable : Cannot remove variable ImAConstant because it is constant or
read-only. If the variable is read-only, try the operation again specifying the Force
option.
At line:2 char:1
+ Remove-Variable -Name "ImAConstant"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (ImAConstant:String) [Remove-Variable], Ses
sionStateUnauthorizedAccessException
+ FullyQualifiedErrorId : VariableNotRemovable,Microsoft.PowerShell.Commands.Remo
veVariableCommand
Set-Variable -Name "ImReadOnly" -Value "Delete me" -Option ReadOnly
Remove-Variable -Name "ImReadOnly" -Force # Removed
These are just a few examples. Pretty cool stuff.
In your function repro
, you use SupportsShouldProcess
in your CmdLetBinding()
but you still need to block it up for your assignment with some code for it to run the way you are thinking.
Function repro {
[CmdletBinding(SupportsShouldProcess)] Param()
if ($pscmdlet.ShouldProcess('$global:foo', "Sets Variable")){
$global:foo = "bar"
}
}
This will produce the same result as your original Set-Variable
call with -WhatIf
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.