locked
Powershell script error RRS feed

  • Question

  • I have this script

    import-module activedirectory
    Import-Csv "c:\util\seext.csv" | ForEach-Object {
    $setpass = ConvertTo-SecureString -AsPlainText $_."password" -force
    $Path = "OU=,DC=,DC="
    New-ADUser `
    -Name $_."user" `
    -Path  $path `
    -SamAccountName  $_."samaccountname" `
    -DisplayName $_."Displayname" `
    -Givenname $_."name" `
    -Surname $_."surname" `
    -UserPrincipalName  $_."UserPrincipalName" `
    -AccountPassword $setpass `
    -ChangePasswordAtLogon $False  `
    -Enabled $true `
    -PasswordNeverExpires $true `
    -EmailAddress  $_."UserPrincipalName"
     }

    When i add in -Office $_."cccID" ' i get the error the string is missing a terminator. It doesn't matter where i add it into the script, is still get the error.

    Thursday, July 27, 2017 5:19 PM

Answers

  • We don't need to do that since PS V1.

    Import-Csv c:\util\seext.csv | 
    	ForEach-Object {
    		$splat = @{
    			Name = $_.user
    			Path = 'OU=,DC=,DC='
    			SamAccountName = $_.samaccountname
    			DisplayName = $_.Displayname
    			Givenname = $_.name
    			Surname = $_.surname
    			UserPrincipalName = $_.UserPrincipalName
    			AccountPassword = ConvertTo-SecureString -AsPlainText $_.password -force
    			ChangePasswordAtLogon = $False
    			Enabled = $true
    			PasswordNeverExpires = $true
    			EmailAddress = $_.UserPrincipalName
    	    }
    		New-ADUser @splat
    	}
    

    Avoid quoting unnecessarily.

    help about_splatting


    \_(ツ)_/

    • Marked as answer by Mgibson-TC Monday, July 31, 2017 2:33 PM
    Thursday, July 27, 2017 5:38 PM

All replies

  • We don't need to do that since PS V1.

    Import-Csv c:\util\seext.csv | 
    	ForEach-Object {
    		$splat = @{
    			Name = $_.user
    			Path = 'OU=,DC=,DC='
    			SamAccountName = $_.samaccountname
    			DisplayName = $_.Displayname
    			Givenname = $_.name
    			Surname = $_.surname
    			UserPrincipalName = $_.UserPrincipalName
    			AccountPassword = ConvertTo-SecureString -AsPlainText $_.password -force
    			ChangePasswordAtLogon = $False
    			Enabled = $true
    			PasswordNeverExpires = $true
    			EmailAddress = $_.UserPrincipalName
    	    }
    		New-ADUser @splat
    	}
    

    Avoid quoting unnecessarily.

    help about_splatting


    \_(ツ)_/

    • Marked as answer by Mgibson-TC Monday, July 31, 2017 2:33 PM
    Thursday, July 27, 2017 5:38 PM
  • Hi,

    Just a modification on the jrv's script:

    $CSV = Import-Csv c:\util\seext.csv
    foreach($account in $CSV)
    {
    	$splat = @{
    		Name = $account.user
    		Path = 'OU=,DC=,DC='
    		SamAccountName = $account.samaccountname
    		DisplayName = $account.Displayname
    		Givenname = $account.name
    		Surname = $account.surname
    		UserPrincipalName = $account.UserPrincipalName
    		AccountPassword = ConvertTo-SecureString -AsPlainText $account.password -force
    		ChangePasswordAtLogon = $False
    		Enabled = $true
    		PasswordNeverExpires = $true
    		EmailAddress = $account.UserPrincipalName
    	        }
            New-ADUser @splat
    }

    ForEach-Object => less memory, slower => should be used for interactive prompt

    traditional foreach(...) => more memory, faster => should be used for scripts

    It is not mandatory, but more a best practice.

    Sunday, July 30, 2017 9:32 PM
  • Not true in most cases.  Under PS V1/2 this was noticeable but in this case the speed is such a trivial part of the issue as the New-AdUser will take all of the time in the loop.

    We can actually reduce the memory to almost nothing by placing the hash outside of the loop and reusing the same hash repeatedly.

    In most real-world applications the ForEach-Object performs better especially when using longer pipelines.  Look at some of the posts on the PowerShell team blog.  They recommend ForEach-Object for most things.

    There are times when foreach() (notice - no caps) is the better choice.  In very long running loops that do small incremental changes the foreach() construct will run noticeably faster.  In the current case the difference will not be noticeable and may be lost do to reading the whole file before enumerating.  Also with very large files the pipeline is usually faster assuming the processing is not trivial.  The small amount of memory used in the pipeline is likely less than loading the whole file into memory before processing it.

    Generating output in a loop with Write-Output will slow the pipeline of the loop.  Write-Host should not impact pipeline or loop.


    \_(ツ)_/


    • Edited by jrv Sunday, July 30, 2017 9:49 PM
    Sunday, July 30, 2017 9:48 PM
  • When i add in -Office $_."cccID" ' i get the error the string is missing a terminator. It doesn't matter where i add it into the script, is still get the error.

    Should that single quote character, ( ' ), be a backtick character, ( ` )?


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Monday, July 31, 2017 1:32 AM
  • I just updated my code to this and it works. Thank you for your help.
    Monday, July 31, 2017 2:34 PM