So I just tried that: [cid:image001.png@01D2159B.16AEBBF0] But when I run the Caller.ps1 I got this: [cid:image002.png@01D2159B.76768A40]
So I tried calling it as ".\add-newuser" but nothing happened. In both scripts I have the functions, but I wasn't calling them within the script. When I added the command to the end of each .ps1 file it ran the Add-NewUser but Enable-UserMailbox was not recognized because it had not loaded into memory I assume: [cid:image003.png@01D2159B.76768A40] Do I need to dot source the Enable-UserMailbox call within the Add-NewUser function? Or is there something else I'm missing. Attaching the script files that generated the above. From: listsad...@lists.myitforum.com [mailto:listsad...@lists.myitforum.com] On Behalf Of Michael B. Smith Sent: Friday, September 23, 2016 12:05 PM To: powershell@lists.myitforum.com Subject: [powershell] RE: Functions, Scoping, and Returns ISE is your issue. It doesn't hand write-host the way you expect (personally, I consider it buggy, but the PG disagrees). Create a file "caller.ps1" consisting of two lines: . .\file1.ps1 . .\file2.ps1 And run it from a PowerShell session .\caller And see if it doesn't behave as you expect. From: listsad...@lists.myitforum.com<mailto:listsad...@lists.myitforum.com> [mailto:listsad...@lists.myitforum.com] On Behalf Of Orlebeck, Geoffrey Sent: Friday, September 23, 2016 2:35 PM To: 'powershell@lists.myitforum.com' Subject: [powershell] RE: Functions, Scoping, and Returns For now each .ps1 file is loaded in a PowerShell ISE session for testing. Once I was comfortable with logic and error handling I want to create a module. I haven't gotten to that step/goal yet, but if that changes the answer, let's work from the premise these will be loaded as a module. From: listsad...@lists.myitforum.com<mailto:listsad...@lists.myitforum.com> [mailto:listsad...@lists.myitforum.com] On Behalf Of Michael B. Smith Sent: Friday, September 23, 2016 11:17 AM To: powershell@lists.myitforum.com<mailto:powershell@lists.myitforum.com> Subject: [powershell] RE: Functions, Scoping, and Returns ATTENTION: This email came from an external source. DO NOT open attachments or click on links from unknown senders or unexpected emails. How are you calling these functions? From: listsad...@lists.myitforum.com<mailto:listsad...@lists.myitforum.com> [mailto:listsad...@lists.myitforum.com] On Behalf Of Orlebeck, Geoffrey Sent: Friday, September 23, 2016 1:38 PM To: 'powershell@lists.myitforum.com' Subject: [powershell] Functions, Scoping, and Returns I have two functions, one for creating an AD account, another for creating a mailbox. The AD account function has a switch for mailbox creation which calls the create mailbox function. The issue I am running into is passing information from the create mailbox back to the parent user creation function. Our Helpdesk staff are not strong with PowerShell and I'm trying to provide text output so they can validate the script worked. The problem I'm encountering is getting both the outputting the 'write-output' steps in the mailbox function and returning a success/fail result. If I store the function in a variable, I can get it to return the success/failure, but it won't output the text as the function runs. If I don't perform a '$Result = create mailbox function', the various outputs from the mailbox function are visible, but then I have no way of validating it actually worked (for screen output purposes of pass/fail.) I'm attaching both functions (scrubbed of any sensitive data), but I'm wondering if this is where scoping gets involved with respect to global/local/script? I'm reading up on the concept but I'm not sure that's the appropriate path. Any help is appreciated. Thank you. Confidentiality Notice: This is a transmission from Community Hospital of the Monterey Peninsula. This message and any attached documents may be confidential and contain information protected by state and federal medical privacy statutes. They are intended only for the use of the addressee. If you are not the intended recipient, any disclosure, copying, or distribution of this information is strictly prohibited. If you received this transmission in error, please accept our apologies and notify the sender. Thank you.
<# .Synopsis Creates a new user account in Active Directory. .DESCRIPTION Creates a new user in AD with options to use an existing user as a template or as a new account without any previous dependencies. By default an Exchange mailbox is created for the user in the same domain. This can be switched off. .EXAMPLE Add-NewUser -Company CHOMP Sets the user's company to "CHOMP". Once started additional info will be requested (Name, EmployeeID, etc.). .EXAMPLE Add-NewUser -NoMailbox The 'NoMailbox' switch means the user will be created but will skip the mailbox creation process .EXAMPLE Add-NewUser -NoCopy The 'NoCopy' switch means no tempalte user will be used during the provisioning process. The user will be created with no additional groups or attributes (Department, Title, etc.) #> function Add-NewUser { [CmdletBinding(DefaultParameterSetName="CopyUser")] #[Alias()] Param ( [Parameter(ParameterSetName="NewUser")] [switch] $NoCopy, [Parameter(Mandatory=$false)] [switch] $NoMailbox, [Parameter(Mandatory=$true,ParameterSetName="CopyUser", ValueFromPipelineByPropertyName=$true)] [Parameter(Mandatory=$true,ParameterSetName="NewUser", ValueFromPipelineByPropertyName=$true)] [ValidateSet("Aspire Health Plan", "CHOMP", "CHI", "Montage Health", "Montage Medical Group")] $Company, [Parameter(Mandatory=$true,ParameterSetName="CopyUser", ValueFromPipelineByPropertyName=$true)] [Parameter(Mandatory=$true,ParameterSetName="NewUser", ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateScript({($_ -match "^[a-zA-Z]") -and ($_ -match "[a-zA-Z]+$")})] $FirstName, [Parameter(Mandatory=$true,ParameterSetName="CopyUser", ValueFromPipelineByPropertyName=$true)] [Parameter(Mandatory=$true,ParameterSetName="NewUser", ValueFromPipelineByPropertyName=$true)] [ValidateScript({($_ -match "^[a-zA-Z]") -and ($_ -match "[a-zA-Z]+$")})] $LastName, [Parameter(Mandatory=$true,ParameterSetName="CopyUser", ValueFromPipelineByPropertyName=$true)] [Parameter(Mandatory=$true,ParameterSetName="NewUser", ValueFromPipelineByPropertyName=$true)] [ValidateScript({$_ -match "^[1-9]"})] [int] $EmployeeID, [Parameter(Mandatory=$false,ParameterSetName="NewUser", ValueFromPipelineByPropertyName=$true)] $PhoneNumber, [Parameter(Mandatory=$false,ParameterSetName="NewUser", ValueFromPipelineByPropertyName=$true)] $OUPath, [Parameter(Mandatory=$false,ParameterSetName="NewUser", ValueFromPipelineByPropertyName=$true)] $Password, [Parameter(Mandatory=$true,ParameterSetName="CopyUser", ValueFromPipelineByPropertyName=$true)] $SourceUser ) Begin { $error.Clear() [bool]$failed = $false [System.Exception]$e = $null [object]$result = $null $SaveEApref = $ErrorActionPreference $ErrorActionPreference = 'Stop' If($Password -eq $null) { $Password = "Password!" } $Cred = Get-Credential Clear-Host } Process { # Store company specific information # $Hash = @{"CHI" = @{"Domain" = "chomp.org"; "EmailDomain" = "chipm.org"; "OUPath" = "CN=Users,DC=chomp,DC=org" "URI"="http://exmail1p.chomp.org/PowerShell/"} "CHOMP" = @{"Domain" = "chomp.org"; "EmailDomain" = "chomp.org"; "OUPath" = "CN=Users,DC=chomp,DC=org" "URI"="http://exmail1p.chomp.org/PowerShell/"} "Montage Health" = @{"Domain" = "chomp.org"; "EmailDomain" = "montagehealth.org"; "OUPath" = "CN=Users,DC=chomp,DC=org" "URI"="http://exmail1p.chomp.org/PowerShell/"} "Aspire Health Plan" = @{"Domain" = "aspirehealthplan.org"; "EmailDomain" = "aspirehealthplan.org"; "OUPath" = "OU=Aspire Users,DC=aspirehealthplan,DC=org" "URI"="http://ahpmail.aspirehealthplan.org/PowerShell/"} "Montage Medical Group" = @{"Domain" = "penpricare.org"; "EmailDomain" = "montagemedicalgroup.org"; "OUPath" = "CN=Users,DC=penpricare,DC=org" "URI"="http://ppcmail.penpricare.org/PowerShell/"} } # Get DC from specified domain [string]$DC = (Get-ADDomainController -Discover -DomainName $($Hash.$Company.Domain)).hostname # Generate UserID (SamAccountname) for AD User creation $UserID = (($FirstName.Substring(0,1)) + ($LastName.Substring(0,1)) + $EmployeeID) If($NoCopy) { Write-Output "Creating new User: $FirstName $LastName ($userID)" $Pswd = ConvertTo-SecureString $Password -AsPlainText -Force $Params = @{Name = "$($LastName.Trim()), $($FirstName.Trim())"; SamAccountName = $UserID; Enabled = $True; UserPrincipalName = "$UserID@$($Hash.$Company.Domain)"; DisplayName = "$($LastName.Trim()), $($FirstName.Trim())"; Company = $Company; EmployeeID = $EmployeeID; GivenName = $($FirstName.Trim()); Surname = $($LastName.Trim()); OfficePhone = $PhoneNumber; Path = $($Hash.$Company.OUPath); Server = $DC Credential = $Cred} # Validate user ID $UserExists = Get-ADUser -Filter {SamAccountName -eq $UserID} If($UserExists) { Write-Warning "$UserID already exists in $($Hash.$Company.Domain)" $Failed = $True } Else { Write-Output "$UserID not found" } If($Failed -eq $False) { Try{ New-ADUser @Params "Successfully created AD account for $UserID" $Failed = !$? } Catch { Write-Warning "Failed to create AD user: $UserID" $Failed = $True } } If($Failed -eq $False) { Write-Output "$UserID AD provisioning completed successfully" } Elseif($failed -eq $true) { Write-Warning "Provisioning of $UserID failed." } } Else { Try { $CopyTo = Get-ADUser $SourceUser -Properties Department,Title,MemberOf -Server $DC -Credential $Cred $Failed = !$? } Catch { Write-Warning "Error: Unable to find source acct: $SourceUser. Aborting user copy." $Failed = $True } If($Failed -eq $False) { Write-Output "Checking $UserID for duplicate name" $UserExists = Get-ADUser -Filter {SamAccountName -eq $UserID} If($UserExists) { Write-Warning "$UserID already exists in $($Hash.$Company.Domain)" $Failed = $True } Else { Write-Output "$UserID not found" } If($Failed -eq $False) { Try{ $OUSplit = $CopyTo.DistinguishedName -split '(?<!\\),' $OUPath = $OUSplit[1..$($OUSplit.Count-1)] -join ',' } Catch { $OUPath = $($Hash.$Company.OUPath) } Write-Output "Creating $UserID using $SourceUser as template" $Pswd = ConvertTo-SecureString $Password -AsPlainText -Force $Params = @{Name = "$($LastName.Trim()), $($FirstName.Trim())"; SamAccountName = $UserID; UserPrincipalName = "$UserID@$($Hash.$Company.Domain)"; Path = $OUPath DisplayName = "$($LastName.Trim()), $($FirstName.Trim())"; Company = $Company; Department = $($CopyTo.Department); Title = $($CopyTo.Title); EmployeeID = $EmployeeID; GivenName = $($FirstName.Trim()); Surname = $($LastName.Trim()); OfficePhone = $PhoneNumber; AccountPassword = $Pswd; Enabled = $True; ChangePasswordAtLogon = $True; Server = $DC Credential = $Cred} Try { New-ADUser @Params Write-Output "Created AD account $UserID@$($Hash.$Company.Domain) successfully" $Failed = !$? } Catch { Write-Warning "Failed to create $UserID from $SourceUser" $Failed = $True Try { Write-Output "Copying group memberships from $SourceUser to $UserID" Foreach($Group in $CopyTo.MemberOf) { Add-ADGroupMember $Group -Members $UserID -Server $DC -Credential $Cred } } Catch { Write-Output "Failed to copy $SourceUser groups to $UserID" } } } } If($Failed -eq $True) { Write-Warning "Provisioning of $UserID failed." } } # Enable Mailbox if user added successfully If(($NoMailbox -eq $False) -and ($Failed -eq $True)) { Write-Warning "Failed to create AD object $UserID" Write-Warning "Aborting Enable-Mailbox operation for $UserID" } Elseif(($NoMailbox -eq $False) -and ($Failed -eq $False)) { $FirstName = $FirstName -replace " " -replace "'" $LastName = $LastName -replace " " -replace "'" $MailParams = @{User = $UserID EmailAddress = "$FirstName.$LastName@$($Hash.$Company.EmailDomain)" Alias = $UserID URI = $($Hash.$Company.URI) Cred = $Cred} Enable-UserMailbox @MailParams } # Result statements If(($NoMailbox -eq $True) -and ($Failed -eq $False)) { Write-Output "No Mailbox requested. Skipping mailbox creation" Write-Output "$UserID provisioning complete" } <# # Validate 'Enable-UserMailbox' completed successfully. # If 'Enable-UserMailbox' returns success and $failed is $false # then return output stating user provisioning is successful ElseIf($Enable-Usermailbox -eq cuess) -and ($failed -eq $false)) #Pseudocode { Write-Output "$UserID provisioned successfully." } #> } # Exit Process block End { } } Add-NewUser
. .\Add-NewUser.ps1 . .\Enable-UserMailbox.ps1
<# .Synopsis Adds mailbox to AD user .DESCRIPTION Dynamically discovers Exchange Mailbox servers in specified domain then enables mailbox against specified user .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet #> function Enable-UserMailbox { [CmdletBinding()] [Alias()] Param ( # Define AD user to enable mailbox [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] $UserID, # Defines primary SMTP address for user [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)] $EmailAddress, # Defines Alias for user's mailbox [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)] $Alias, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)] $Cred, $URI ) Begin { } Process { Write-Output "Establishing Exchange server connection" $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $URI -Authentication Kerberos -Credential $Cred Import-PSSession $Session -DisableNameChecking -AllowClobber | Out-Null Write-Host "Attempting mailbox creation for $UserID" Try { Enable-Mailbox $UserID -PrimarySMTPAddress $EmailAddress -Alias $Alias | Out-Null Write-Output "Created mailbox for $UserID`: $EmailAddress" Get-PSSession | Remove-PSSession } Catch { Write-Warning "Failed to create $EmailAddress mailbox." Get-PSSession | Remove-PSSession } } End { If(Get-PSSession) { Get-PSSession | Remove-PSSession } } } Enable-UserMailbox