Syntax Issues Syntax Powershell vs Powershell Universal

Product: PowerShell Universal
Version: 5.0.7

I have noticed that there seems to be a disconnect or maybe it’s just me, but I am really hoping that you might be able to help me, maybe others by answering this question.

I often find that what works in a already useful Powershell script doesn’t always transfer to Powershell Universal. I am not sure why. It appears to be a difference in how Powershell Universal deploys the script or possibly that the syntax is different. In any case I can’t seem to find an answer in the available documentation.

Here is an example of a known working script that I simply can’t make work in Powershell Universal. It takes a csv file then creates AD and Google Workspace accounts. You feed is appreciated.

Define the path to the CSV file on the user’s desktop

$csvPath = [System.IO.Path]::Combine([System.Environment]::GetFolderPath(‘Desktop’), ‘defaultUsers.csv’)

Check if the CSV file exists

if (-Not (Test-Path $csvPath)) {
Write-Host “CSV file not found: $csvPath”
exit 1
}

Import the CSV file

$users = Import-Csv -Path $csvPath

Define the list of groups to which each user will be added (excluding Domain Users)

$groups = @(
‘$Avixxxhers’,
‘$Stuxxolder’,
‘$Txxers’,
‘$Wxeach’
)

Define the distinguished name of the template user

$templateUserDN = “CN=Txer Template,OU=Inx Accounts,OU=Texers,OU=Users,OU=XXXX,DC=XXXX,DC=XXXXX”

Get the template user

$templateUser = Get-ADUser -Identity $templateUserDN -Properties *

Loop through each user in the CSV file and create the AD user and run the gam command

foreach ($user in $users) {
if ($user.email -and $user.firstName -and $user.lastName -and $user.password -and $user.orgUnitPath) {
$email = $user.email
$firstName = $user.firstName
$lastName = $user.lastName
$password = $user.password
$orgUnitPath = $user.orgUnitPath
$username = $email -replace “@XXXXX.org”, “”
$displayName = “$firstName $lastName”
$logonScript = “Texgon”
$targetOU = “OU=Txrs,OU=Users,OU=XXXX,DC=XXXX,DC=XXXXX”

    Write-Host "Processing user: $username"

    
    }

    # Create the AD user by copying the template user's properties
    New-ADUser `
        -Name "$firstName $lastName" `
        -GivenName $firstName `
        -Surname $lastName `
        -UserPrincipalName "$username@XXXX.XXXXX" `
        -SamAccountName $username `
        -Path $targetOU `
        -DisplayName $displayName `
        -ScriptPath $logonScript `
        -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) `
        -Enabled $true `
        -Description $templateUser.Description `
        -OfficePhone $templateUser.OfficePhone `
        -EmailAddress $email `
        -StreetAddress $templateUser.StreetAddress `
        -City $templateUser.City `
        -State $templateUser.State `
        -PostalCode $templateUser.PostalCode `
        -Country $templateUser.Country `
        -Title $templateUser.Title `
        -Department $templateUser.Department `
        -Company $templateUser.Company

    # Get the created AD user to ensure the user exists
    $createdUser = Get-ADUser -Identity $username

    # Add the new user to the specified security groups
    foreach ($group in $groups) {
        $groupObject = Get-ADGroup -Filter { Name -eq $group }
        if ($null -ne $groupObject) {
            Write-Host "Adding to AD group: $group"
            Add-ADGroupMember -Identity $groupObject -Members $createdUser
        } else {
            Write-Host "Group $group not found"
        }
    }

    # Set additional properties if necessary
    Set-ADUser -Identity $createdUser -HomeDirectory $templateUser.HomeDirectory -HomeDrive $templateUser.HomeDrive

    Write-Host "User $username processed successfully."
}

#Call CreateGWorkspaceUsers

Get the current user’s desktop path

$desktopPath = [Environment]::GetFolderPath(‘Desktop’)

Define the path to the script

$scriptPath = Join-Path -Path $desktopPath -ChildPath ‘CreateGWorkspaceUsers.ps1’

Execute the script

& $scriptPath

Write-Host “All users have been processed.”

Define the prompt message

$promptMessage = "
GAM must be installed!

This script will create users in Google Workspace and add them to specific groups.
You must have a csv file on your desktop that contains the following headers (case sensitive):

firstName
lastName
email
password
orgUnitPath (use /Staff Members)

Do you want to continue? (y/n): "

Function to get the user’s input

function Get-UserInput {
param (
[string]$message
)
Write-Host -NoNewline $message
$input = Read-Host
return $input
}

Main script logic

while ($true) {
$userInput = Get-UserInput -message $promptMessage
switch ($userInput.ToLower()) {
‘y’ {
# Define the path to the CSV file on the user’s desktop
$csvPath = [System.IO.Path]::Combine([System.Environment]::GetFolderPath(‘Desktop’), ‘defaultUsers.csv’)

        # Check if the CSV file exists
        if (-Not (Test-Path $csvPath)) {
            Write-Host "CSV file not found: $csvPath"
            exit 1
        }

        # Import the CSV file
        $users = Import-Csv -Path $csvPath

        # Define the list of groups to which each user will be added
        $hardcodedGroups = @(
            "axff",
            "classroxhers",
            "txrs",
            "RaxementUser",
            "Raxdmin"
        )

        # Loop through each user in the CSV file and run the gam command
        foreach ($user in $users) {
            $email = $user.email
            $firstName = $user.firstName
            $lastName = $user.lastName
            $password = $user.password
            $orgUnitPath = $user.orgUnitPath

            # Construct the gam command to create the user
            $gamCommand = "gam create user $email firstname `"$firstName`" lastname `"$lastName`" password `"$password`" org `"$orgUnitPath`""

            # Run the gam command in a cmd window
            Start-Process cmd.exe -ArgumentList "/c $gamCommand" -NoNewWindow -Wait

            # Loop through each hardcoded group and add the user as a member
            foreach ($group in $hardcodedGroups) {
                $addGroupCommand = "gam update group $group add member $email"
                Start-Process cmd.exe -ArgumentList "/c $addGroupCommand" -NoNewWindow -Wait
            }

            # Add user to Staff - XXXXX calendar
            $addCalendarCommand = "gam calendar XXXXX_XXX@group.calendar.google.com add reader $email"
            Start-Process cmd.exe -ArgumentList "/c $addCalendarCommand" -NoNewWindow -Wait
        }

        Write-Host "All users have been processed."

        break
    }
    'n' {
        Write-Host "Terminating..."
        exit
    }
    default {
        Write-Host "Invalid input. Please enter 'y' or 'n'."
    }
}

}

At what point are you getting errors? It seems to me the problem may stem from the use of [System.Environment]::GetFolderPath('Desktop') but it’s unclear at this point.

Hi Zoe,

Thank you for your reply. I probably should have started with a more simple question. I have attempted creating various PS scripts that create a user in Active Directory and add them to several groups. It doesn’t appear to matter, whether I am importing the users or hard coding the information. The script run fine when launched on the domain controller, it only fails when ran from within Powershell Universal. Powershell Universal is also running on the DC and when I execute the run on powershell 5.1 and on the remote DC hosting Active Directory. It appears to be a permissions issue. Again, the script works find when ran from PS but not via PSU. I guess my question is more simple in that I need to figure out how to authenticate or pass credentials to the DC to allow the script to run. I have set the execution policy to remotesigned. Any ideas or be appreciated. Thank you.

User credentials can be added in the Variables section, within Platform → Variables → Create Secret. Set the type to PSCredential and fill in the user credentials there. After this point, you can use the RunAs feature of scripts to, well, run the script as that user. It may be worth creating a PSU service account to delegate the permissions as needed from there.

That’s probably the easiest way to do it. Let me know if that helps!

Thanks for your help Zoe! I’ll have to play around with this feature and do some looking in to the documentation. I’m still missing something but I’m a little further along :).

1 Like