Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 474
  • Last Modified:

Powershell Functions

I'm kinda new to Power-Shell and my previous scripting experience was DOS Batch as well as a little Perl several years ago, but in both cases most of my scripts were at the largest about 100 lines so I never bothered much with Functions. I am now attempting to write a very large script and wanted to keep it organized by using Functions, but I'm having issues...

Can somebody explain to me how to make variables work between functions and the root level of the script in a powershell script? For example, why doesn't this work:
Function Get-NewUserInfo
{
$fname = (Read-Host "First Name")
$lname = (Read-Host "Last Name")
$mi = (Read-Host "Middle Initial")
$job = (Read-Host "Job Title")
$dept = (Read-Host "Department")
}

Get-NewUserInfo

Write-Host ""
Write-Host $fname
Write-Host $mi
Write-Host $lname
Write-Host $job
Write-Host $dept

Open in new window


Thanks,
-Al
0
Cacophony777
Asked:
Cacophony777
  • 2
  • 2
1 Solution
 
QlemoC++ DeveloperCommented:
The default scope of vars is "local to script block". A function builds an own script block, and hence all vars set therein are volatile. You can use something like
$script:fname = (Read-Host "First Name")

Open in new window

in your function. If you use $global, the vars are set for the scope of the PowerShell session.
0
 
Cacophony777Author Commented:
So once I call that variable by $script:fname is it available to the entire script for the duration of it's run? ...or if another function in my script needs to modify that same variable do I have to again refer to it by $script:fname?

Also, is there a way to tell my script that I want all variable I use set to the "Script" scope?
0
 
QlemoC++ DeveloperCommented:
If you access $fname, it should be available everywhere. However, if you try to set it, you will create a local instance of that var. Example:
function test
{
  Write-Host $var
  $script:var = "set in function,#1"
  Write-Host $var
  $var = "set in function,#2"
  Write-Host $var
}

Cls
$var = "set in script"
test
Write-Host $var

Open in new window

You can't change or set a default scope, sorry. It is an intentional implemention detail of PowerShell that all changes should be local by default.
Causing side-effects like setting global vars in a function is considered bad practice anyway. You should construct an object, change it attributes, and use that object for the "interface":
Function Get-NewUserInfo ($emp)
{
  $emp.fname = Read-Host "First Name"
  $emp.lname = Read-Host "Last Name"
  $emp.mi    = Read-Host "Middle Initial"
  $emp.job   = Read-Host "Job Title"
  $emp.dept =  Read-Host "Department"
}

$emp = New-Object PSObject
"fname","lname","mi","job","dept" | % { Add-Member -InputObject $emp NoteProperty $_ "" -PassThru }
      
Get-NewUserInfo($emp)

$emp | format-list

Open in new window

I know this is much different from cmd batches, however it is an important step to write "PowerShell'ish" in a proper way ;-).
0
 
Cacophony777Author Commented:
Thanks... great explanation!
0

Featured Post

Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now