How to pass variables from one function to another?

I have a function where i define all the variables from an import-CSV and pipe them to a function that creates new users.

Function newaduser {
[CmdletBinding()]
Param (
$Userspassword = “Hellow0rld45684654@[!”,

[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]
$Username,

[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]
$FirstName,

[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]
$surname,

[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]
$dispname,

[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]
$desc,

[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]
$title,

[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]
$depar,

[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]
$telnumber,

[Parameter(ValueFromPipelineByPropertyName = $true)]
[string]
$SamName

)

process
{
       $CreateSecure =(ConvertTo-SecureString $Userspassword -AsPlainText -Force)

New-aduser -AccountPassword $CreateSecure -changepasswordatlogon $false -enabled $true -Name $Username -GivenName $firstname -surname $surname -DisplayName $dispname -EmailAddress "$SamName@ourcompany.com" -SamAccountName $SamName -userprincipalname $SamName -Description $desc -Title $title
-Department $depar -OfficePhone $telnumber -Company iPipelineUK -City Cheltenham -State Gloucestershire -PostalCode GL501TA
}
}

import-csv -Path C:\UserInput.csv | newaduser

I then have some error handling to see if the users were created successfully, if they are then another set of functions are called that send emails to various people asking them to create an account for each new user account that has been created.

if($error.count -eq 0)
{
Write-Host “”
Write-Host -BackgroundColor Yellow -ForegroundColor Black " Users Succesfully Created "
Write-Host “---------------------------------------------------------------”
SendSuccess-Email
SendWebEx-Email
SendPIPEDomain-Email
SendKapta-Email
SendProjector-Email
}
Else
{
Write-Host “”
Write-Host -BackgroundColor red -ForegroundColor Black " Users Failed to be Created"
Write-Host “--------------------------------------------------------------”
SendFailure-Email
}

What i want to do is call the variables $FirstName and $surname from my newaduser function and include them in the body of the emails i will be sending to each person.

Function SendProjector-Email {
Write-Host “”
Write-Host " Projector account request email sent."
Write-Host “---------------------------------------------------------------”
$emailFrom = “jjones@ourcompany.com
######Use commas for multiple addresses
$emailTo = “jjones@ourcompany.com
$subject = “Projector account for new user”
$body = "Hi Helpful Person,

Please could you create a Projetor account for $FirstName $surname. Please let me know if you need any additional information.

Kind regards,

The Guy Who Setup The Accounts"
$smtpServer = “smtprelay.ourcompany.co.uk
######creating the sendobject
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
######sending the email
$smtp.Send($emailFrom, $emailTo, $subject, $body)
}

When i try this the emails don’t show anything for the $FirstName and $surname variables, its just blank. So i know the variables from the newaduser aren’t being passed to these functions. Is there a way to do this? Also it would be ideal if i could do this FOR EACH user. I dont know if this would already happen because at present the newaduser function creates each user from the CSV without me explicitly doing some kind of For Each statement.

Thanks in advance!

Please consider formatting your code using the HTML PRE tag, or attaching long scripts like this as a TXT file. It’s a bit hard to read as-is.

Your SendProjector-Email function is in a separate scope; you technically should define parameters within it, and pass values to it that way.

function SendProjector-Email {
 param ($firstname,$surname)
 ...
}

You would then call that with:

SendProjector-Email -firstname $firstname -surname $surname

From within your main function.

Also, if you’re interested, the naming convention in PowerShell is “verb-noun.” So, “Send-ProjectorEmail” might be a more appropriate name if you wanted to stay consistent.

Thanks for the advice regarding naming conventions and presenting the code in a more readable manner.

I understand what you are trying to do here but i don’t want to have to call each email function and define the parameters for each user that is created, I want each email function to grab each user that is being created from the csv file in the New-aduser function. Specfically the variables $firstname and $surname.

I think with the method you have suggested i would still have to define the $firstname and $surname for each user when calling the SendProjector-Email function?

Please correct me if i am wrong.

I have tried getting this to work by calling the SendProjector-Email function within my new-aduser function. It does work, it sends a request email for each of the users in the csv file. But the problem i have is that the error checking wont work. AT present i have an error clear, import my csv, pipe it to the new-aduser function and error count check after. The script then sends the email requests by calling the email function if the error count is 0. If i try and incorporate this logic into my script it doesn’t work. For example if the users are already present and i run the script it should send the failure email, however it still runs the success email part of the if statement.

Function newaduser {
[CmdletBinding()]
Param (
    $userspassword = "Hellow0rld45684654@[!",

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $username,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $firstName,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $surname,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $dispname,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $desc,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $title,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $depar,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $telnumber,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $SamName

    )

    process
    {
           $CreateSecure =(ConvertTo-SecureString $Userspassword -AsPlainText -Force)

$error.clear()


New-aduser -AccountPassword $CreateSecure -changepasswordatlogon $false -enabled $true -Name $username -GivenName $firstname -surname $surname `
-DisplayName $dispname -EmailAddress "$SamName@ipipeline.com" -SamAccountName $SamName -userprincipalname $SamName -Description $desc -Title $title `
-Department $depar -OfficePhone $telnumber -Company iPipelineUK -City Cheltenham -State Gloucestershire -PostalCode GL501TA

if($error.count -eq 0) 
	{
    	Write-Host ""
        Write-Host -BackgroundColor Yellow -ForegroundColor Black " Users Succesfully Created "
        Write-Host "---------------------------------------------------------------"
        SendSuccess-Email
        foreach-object {SendWebEx-Email -firstname $_.firstname -surname $_.surname}
        foreach-object {SendPIPEDomain-Email -firstname $_.firstname -surname $_.surname}
        foreach-object {SendKapta-Email -firstname $_.firstname -surname $_.surname}
        foreach-object {SendProjector-Email -firstname $_.firstname -surname $_.surname}
	}
    Else 
    {
        Write-Host ""
        Write-Host -BackgroundColor red -ForegroundColor Black " Users Failed to be Created"
        Write-Host "--------------------------------------------------------------"
        SendFailure-Email
    }

    }
}
Is this the only way i can get the $firstname and $surname parameters from my new-aduser function to pass to my send-projectoremail function?

Eureka!

 Function SendProjector-Email {
[CmdletBinding()]
 param (    
 
    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $firstName,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $surname
        )
Write-Host ""
Write-Host " Projector account request email sent."
Write-Host "---------------------------------------------------------------"
        $emailFrom = "jjones@ipipeline.com"
        ######Use commas for multiple addresses
        $emailTo = "jjones@ipipeline.com"
        $subject = "Projector account for new user"
        $body = "Hi Kim/Lauren,
        
Please could you create a Projetor account for $firstName $surname. Please let me know if you need any additional information.
        
Kind regards,
        
UK Technology Services"
        $smtpServer = "smtprelay.assureweb.co.uk"
        ######creating the sendobject
		$smtp = new-object Net.Mail.SmtpClient($smtpServer)
		######sending the email
        $smtp.Send($emailFrom, $emailTo, $subject, $body)
        }  
      import-csv -Path C:\Users\jjones\Desktop\NewADUser.csv | foreach-object {SendProjector-Email -firstName $_.firstName -surname $_.surname}

Managed to figure it out myself :slight_smile: Thanks for your help!