PXE Powershell FindAll() ComException

I have a powershell script that we use during a Microsoft SCCM PXE task sequence for naming a PC. It worked flawlessly until a recent upgrade to SCCM 2012 R2 by the primary server admin.
Now when the code runs search if a user is in a specified AD group needed to complete the PXE build it gives this COM error
Exception calling "FindAll" with "0" argument(s): "Unknown error (0x80005000)"
At X:\Windows\System32\OSD\x86_PXE.ps1:202 char:1
+ $colResults = $objSearcher.FindAll() # Finds all items that match search and put ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : COMException
I have searched far and wide to try and solve this. It seems like a .Net error but I have been unsuccessful in resolving it.
Below is the relevant code. Note that this is being ran in Windows PE that is included with SCCM 2012 R2 as well as the current Windows ADK. It is most likely going to work just fine on a normal PC as it does on mine.
Things to note, you will need to change to match you environments
 - $Domain 
 - $strFilter - specifically "Memberof=cn=<AD_group>"
 - $objOU - server path 
function get-humadcreds {
$global:creds = get-credential -message "Please authenticate to Domain"
$global:UserName = $creds.username
$global:encPassword = $creds.password
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($encpassword)) # Converts secure string to plain text
$Domain = #Domain
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$pc = New-Object System.DirectoryServices.AccountManagement.PrincipalContext $ct,$Domain
$authed = $pc.ValidateCredentials($UserName,$Password)
# Recursively requests credentials if authorization fails
if ($authed -eq $false)
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.MessageBox]::Show("Authentication failed - please retry!")
get-humadcreds
get-humadcreds # Gets AD credentials from user
###Provisioning Authentication
$strFilter = "(&(objectCategory=user)(SAMACCOUNTNAME=$global:UserName)(|(Memberof=cn=,OU=Delegation,OU=HQ,dc=,dc=,dc=)))" # Filter for searching
$decodedpassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($encpassword)) # Decoded password from AD Auth
$objOU = New-Object System.DirectoryServices.DirectoryEntry("LDAP://server/OU=HQ,dc=,dc=,dc=",$global:username,$decodedpassword) # Authentication must specify domain controller
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objOU # Starts search in this OU
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter # Applies filter to search
$objSearcher.SearchScope = "Subtree"
$colProplist = "name"
$isInProvGroup = $False # Defaults value to false.
echo $objSearcher >> C:\Windows\System32\OSD\results.txt
$colResults = $objSearcher.FindAll() # Finds all items that match search and puts them in array $colResults
echo $colResults
foreach ($objResult in $colResults)
$isInProvGroup=$True #If user is in D_HQ_AddComputers (if $colResults is not empty), result will be true
echo $isInProvGroup
PE OS Verson 6.3.9600.16384

I found my solution.
Previously in SCCM 2012 prior to R2 the boot image was a Windows 8 PE4 image in which we had to integrated ADSI back into to using a version of it written by Johan
Arwidmark. This can be found
here for reference. 
This time around after the R2 update and subsequently the forced upgrade of the boot images to 8.1 PE5 since no prior boot images would boot from PXE we had to add ADSI back in again this time from
here. Previously and this time it was done through the configuration manager under drivers, its added as a driver with its required files and is added as a driver component into the boot.wim but in reality after digging for quite some time I found that
it wasn't actually adding the needed dll files into the image even though the operation returned successful. 
What I ended up doing was manually mounting the wim file on my PC with DISM, adding the driver from a folder, allowing unsigned ones to be installed. then manually verified the dlls were put into place in <boot.wim_windir>\System32. After I did that
I was able to unmount the wim committing changes, replace the boot wim used by the server, distribute content and test it. Which was successful.
Just as a reference, the required files are listed below. In my case they had to come from a Windows 8.1 32bit install. If going for 64bit they have to come from a computer or image with Windows 8.1 64bit
adsldp.dll
adsmsext.dll
adsnt.dll
mscoree.dll
mscorier.dll
mscories.dll

Similar Messages

  • Cannot create mysites from powershell: Original XSLT List View Web Part not found

    I have a bizarre problem in my SharePoint 2013 farm. This does not occur in my test farm, only in the farm we were going to go live with.
    I'm on windows Server 2012, SQLServer 2012 SP1, SharePoint 2013 April CU. 1 appserver/centraladmin server, 2 web servers.
    When I log into our mysitehost and click newsfeed, it will create a mysite (even though first it displays "we are sorry there was a problem creating your site")
    But from powershell, whether I use $UserProfile.CreatePersonalSite() or New-SPSite, I get the following error:
    Original XSLT List View Web Part not found
    So far I've only found one other person with this:
    http://social.msdn.microsoft.com/Forums/sharepoint/en-US/2503e42c-e114-4e89-8e00-89fe70f0b154/cannot-create-sharepoint-mysite-programmatically
    This is a brand new farm, created with the same scripts I created my test farm with, and same version of SharePoint. Only the service accounts are different. (Farm account has admin on the servers right now since I was setting up profile service).
    Some other errors from the same correlation ID that look related:
    It can't seem to find the listemplate 101
    And something looks wrong with the MySiteDocumentLibrary feature
    I have tried the following:
    1. run psconfig.exe on each server
    2. install-spfeature -AllExistingFeatures
    3. looped through the directory under Features and for each called Install-SPFeature $dirname -Force
    4. uninstalled and reinstalled MySiteDocumentLibrary feature
    5. blew away the whole farm (removed all servers from farm, deleted all databases) and recreated it.
    6. tried creating the UPA from the CentralAdmin gui.
    The only real difference I can think of between the working farm and non working farm is, I installed the working farm using RTM, then as they came out added the March PU and April CU. For this farm I installed RTM and March and April, and then ran my build
    farm script.
    I am at a loss. What do I need to do, re-install the binaries? That's all I can think of. What I love is that our test / POC system worked fine, and now 2 weeks before go-live I'm seeing errors on the production servers I've never seen before. Using the
    same scripts no less.
    Feature Activation: Feature 'Fields' (ID: 'ca7bd552-10b1-4563-85b9-5ed1d39c962a') was activated
    Feature Activation: Feature 'CTypes' (ID: '695b6570-a48b-4a8e-8ea5-26ea7fc1d162') was activated
    No document templates uploaded for list "$Resources:core,global_onet_solutiongallery_list;" -- none found for list template "100"
    Failed to find <ListTemplate> tag corresponding to ID "101", tried both onet.xml for site definition ID "0" language "1033" and global site definition. Operation failed.
    No document templates uploaded for list "$Resources:core,stylelibraryList;" -- none found for list template "121".
    System.Runtime.InteropServices.COMException: A user may not remove his or her own account from a site collection.<nativehr>0x81020051</nativehr><nativestack></nativestack>, StackTrace: at Microsoft.SharePoint.SPUserCollection.UpdateMembers
    Feature Activation: Feature 'MySitePersonalSite' (ID: 'f661430e-c155-438e-a7c6-c68648f1b119') was activated
    Feature Activation: Activating Feature 'MySiteDocumentLibrary'
    Calling 'FeatureActivated' method of SPFeatureReceiver for Feature 'MySiteDocumentLibrary'
    SharePoint Foundation Upgrade MySiteDocumentLibraryFeatureReceiveraj08n INFO Creating new My Documents library
    Unknown SPRequest error occurred. More information: 0x80070002
    SPRequest.GetMetadataForUrl: UserPrincipalName=, AppPrincipalName= ,bstrUrl=http://contoso/personal/cbuchholz/DOCUMENTS ,METADATAFLAGS=59
    System.IO.FileNotFoundException: <nativehr>0x80070002</nativehr><nativestack></nativestack>, StackTrace: at Microsoft.SharePoint.SPWeb.GetObjectForUrl at Microsoft.SharePoint.Portal.UserProfiles.MySiteDocumentLibraryUtil.GetSPObjectFromUrl ...
    <nativehr>0x80070002</nativehr><nativestack></nativestack>There is no Web named "/personal/cbuchholz/DOCUMENTS"
    Possible mismatch between the reported error with code = 0x81070504 and message: "There is no Web named "/personal/cbuchholz/DOCUMENTS"." and the returned error with code 0x80070002.
    Attemping to add webpart id 0F6072F2-E804-4CFD-837E-BB37332B9D1C to web http://contoso/personal/cbuchholz
    Adding XsltListViewWebPart calling SPRequest::CreateListViewPart. Web part id 0F6072F2-E804-4CFD-837E-BB37332B9D1C, web http://contoso/personal/cbuchholz
    Feature receiver assembly 'Microsoft.SharePoint.Portal, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c', class 'Microsoft.SharePoint.Portal.UserProfiles.MySiteDocumentLibraryFeatureReceiver', method 'FeatureActivated' for feature 'e9c0ff81-d821-4771-8b4c-246aa7e5e9eb' threw an exception: System.InvalidOperationException: Original XSLT List View Web Part not found at Microsoft.SharePoint.Portal.UserProfiles.MySiteDocumentLibraryUtil.ReplaceListViewWebPart
    Feature Activation: Threw an exception, attempting to roll back. Feature 'MySiteDocumentLibrary'
    Exception in EnsureFeaturesActivatedAtSite: System.InvalidOperationException: Original XSLT List View Web Part not found
    Failed to activate site-collection-scoped features for template 'SPSPERS#2' in site collection 'http://contoso/personal/cbuchholz'
    Failed to apply template "SPSPERS#2" to web at URL "http://contoso/personal/cbuchholz
    I've had other problems in this farm: the bug where when you add Administrators to a Search Service via the Manage Service Applications page, it removes the SPSearchDBAdmin role from the search service process account. That one did not happen in the other farm.
    At least other people have that one and I could just use the farm admin instead (still troublng of course).

    Ok,
    Here is the problem:
    When creating a mysite from powershell or script, apparently you can ONLY do this from a wfe (or a server running Microsoft SharePoint Foundation Web Application in services on server).
    You CANNOT create mysites from script on your appserver if it is not also a Web Application Server. I confirmed the same is true in my test farm. I guess I was always running most of these scripts on the webserver.
    I searched all over and cannot find this documented anywhere.
    Who do I contact to have Microsoft document this?
    It's Thursday morning, I've been working non stop since Saturday morning so you don't have to :)

  • Powershell Script to create "custom" Document Library

    I have a powershell script which creates a Document Library for every user in AD.
    This works, but rather than using the default Document Library I want it use a custom Document Library.  However this isnt working.
    My script to create the default Document Library is this...
    [System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
    $site = new-object Microsoft.SharePoint.SPSite("http://servername/sitename");
    $siteweb = $site.OpenWeb();
    $webs = $siteweb.Webs;
    $strFilter = "(&(objectCategory=User)(name=accountname))"
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain
    $objSearcher.PageSize = 1000
    $objSearcher.Filter = $strFilter
    $objSearcher.SearchScope = "Subtree"
    $colProplist = "samaccountname"
    foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
    $colResults = $objSearcher.FindAll()
    foreach ($objResult in $colResults)
    $objItem = $objResult.Properties; $objItem.samaccountname
    $listTemplate = [Microsoft.SharePoint.SPListTemplateType]::DocumentLibrary
    $listId = $siteweb.Lists.Add($objItem.samaccountname, "", $listtemplate);
    $list = $siteweb.Lists.GetList($listId, $true);
    $roleDef = $siteweb.RoleDefinitions.GetByType("Contributor");
    $user = "domain\" + $objItem.samaccountname;
    $rolAssign = new-object Microsoft.SharePoint.SPRoleAssignment($user, "email", "name", "notes");
    $rolAssign.RoleDefinitionBindings.Add($roleDef);
    if(!$list.HasUniqueRoleAssignments)
    {$list.BreakRoleInheritance($true);}
    for ($i = $list.roleAssignments.Count - 1; $i -gt -1; $i--)
    { $list.RoleAssignments.Remove($i) }
    $list.RoleAssignments.Add($rolAssign);
    $list.Update();
    Now I have a custom Document Library named "TESTLIB" so if I substitute the line:
    $listTemplate = [Microsoft.SharePoint.SPListTemplateType]::DocumentLibrary
    with
    $listTemplate = [Microsoft.SharePoint.SPListTemplateType]::TESTLIB
    Then it errors with this...
    How can I script powershell to create a "custom" Document Library?
    Thanks

    The below link should help you in creating custom document library using powershell
    http://blogs.technet.com/b/heyscriptingguy/archive/2010/09/23/use-powershell-cmdlets-to-manage-sharepoint-document-libraries.aspx
    Vinod H
    Thanks for the link but I cant see anything to assist creating a custom library?  Was there something in paticular you saw?

  • PowerShell script for AD name change

    I need to change all users logon name in AD to their first name.last name    Server 2003

    Here is my suggestion of a PowerShell V1 script to rename all users (sAMAccountName):
    # Filter on all users that have givenName and sn assigned.
    $searcher=[adsisearcher]'(&(objectCategory=person)(objectClass=user)(givenName=*)(sn=*))'
    [void]$searcher.PropertiesToLoad.Add('distinguishedName')
    [void]$searcher.PropertiesToLoad.Add('sAMAccountName')
    [void]$searcher.PropertiesToLoad.Add('givenName')
    [void]$searcher.PropertiesToLoad.Add('sn')
    $searcher.PageSize
    = 200
    $Results =
    $searcher.FindAll()
    ForEach ($Result
    In $Results)
        # Retrieve values.
        $DN
    = $Result.Properties.Item("distinguishedName")
        $NTName
    = $Result.Properties.Item("sAMAccountName")
        $First
    = $Result.Properties.Item("givenName")
        $Last
    = $Result.Properties.Item("sn")
        # Construct desired "pre-Windows 2000 logon" name.
        $NewName
    = "$First.Last"
        # Make sure new name 20 characters or less.
        If ($NewName.Length
    -gt 20)
            # I don't know how to trim $First in PowerShell to make $NewName 20 characters.
        # Check if name should be updated (case insensitive).
        If ($NTName
    -ine $NewName)
            # Trap possible error.
            Trap
                "Unable to rename user $DN to $NewName"
                "Error description: $_"
                Continue
            # Bind to user object in AD.
            $User
    = [ADSI]"LDAP://$DN"
            # Assign new name.
            $User.sAMAccountName
    = $NewName
            # Save the change to AD.
            $User.SetInfo()
    Test first, by commenting out the SetInfo() statement and echo $DN and $NewName for all  users. Note that the script could trim $First to limit $First.$Last to 20 characters, but I could not find a way to do this. Also, this script does nothing to prevent
    duplicate sAMAccountName values, but the possible error will echo to the screen.
    Richard Mueller - MVP Directory Services

  • Powershell Copy User Description from one Domain to another in one Forest

    Hi.
    I would like to copy the Description field from one domain to another domain in the same forest.
    First I would like to get the following data from source domain
    - SamAccountName
    - Description
    - Office
    - Job Title
    - Department
    - Manager
    I would like to get these informations to a txt-file. That I can manage myself, I think.
    These values shoud then be set on the destination domain - and here my powershell skills are not suffecient. How do I add these values from txt-file to existing users? (if some users aren't there, the script should continue)....
    I can Get-AdUser -Identity xxx -Server sourcedomain and Get-AdUser -Identity xxx -Server destinationdomain from the same powershell windows.
    Regards
    Carsten
    Carsten

    Hi. Thank you very much for helping me out. I tried the above script and added in additional properties.
    When I run the script, I only get one line in my csv-file, the Office-field is empty and all items appear on screen instead of output to file.
    The script looks as follows:
    $ou = [adsi] "LDAP:<Server>"
    $searcher = New-Object System.DirectoryServices.DirectorySearcher $ou
    $searcher.Filter = 'objectClass=user'
    $result = $searcher.FindAll()
    foreach($contacts in $result)
     $contact = $contacts.GetDirectoryEntry()
     $contact | Select-Object -Property @{Name="SamAccountName";Expression={$_.SamAccountName}},
               @{Name="Description";Expression={$_.Description}},
               @{Name="Office";Expression={$_.Office}},
               @{Name="Title";Expression={$_.Title}},
               @{Name="Department";Expression={$_.Department}},
               @{Name="Manager";Expression={$_.Manager}}
    $contacts | Export-Csv -Path output.csv
    Carsten

  • Powershell script assistance - adding another property to existing script

    This is not my script but was written by Richard L. Mueller. It works perfectly for us but I would like to know if the account is enabled or disabled when the output is created. Basically it would output the name, lastlogon and then either enabled or disabled.
    I've attempted to add a new property by adding another " $Searcher.PropertiesToLoad.Add" and "$Result.Properties.Item ".
    It works fine if I add something like "givenName" but I can't find the property name to show if the account is enabled or disabled.
    The entire script is shown below:
    # PSLastLogon.ps1
    # PowerShell script to determine when each user in the domain last
    # logged on.
    # Copyright (c) 2011 Richard L. Mueller
    # Hilltop Lab web site - http://www.rlmueller.net
    # Version 1.0 - March 16, 2011
    # This program queries every Domain Controller in the domain to find the
    # largest (latest) value of the lastLogon attribute for each user. The
    # last logon dates for each user are converted into local time. The
    # times are adjusted for daylight savings time, as presently configured.
    # You have a royalty-free right to use, modify, reproduce, and
    # distribute this script file in any way you find useful, provided that
    # you agree that the copyright owner above has no warranty, obligations,
    # or liability for such use.
    Trap {"Error: $_"; Break;}
    $D = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $Domain = [ADSI]"LDAP://$D"
    $Searcher = New-Object System.DirectoryServices.DirectorySearcher
    $Searcher.PageSize = 200
    $Searcher.SearchScope = "subtree"
    $Searcher.Filter = "(&(objectCategory=person)(objectClass=user))"
    $Searcher.PropertiesToLoad.Add("distinguishedName") > $Null
    $Searcher.PropertiesToLoad.Add("lastLogon") > $Null
    # Create hash table of users and their last logon dates.
    $arrUsers = @{}
    # Enumerate all Domain Controllers.
    ForEach ($DC In $D.DomainControllers)
    $Server = $DC.Name
    $Searcher.SearchRoot = "LDAP://$Server/" + $Domain.distinguishedName
    $Results = $Searcher.FindAll()
    ForEach ($Result In $Results)
    $DN = $Result.Properties.Item("distinguishedName")
    $LL = $Result.Properties.Item("lastLogon")
    If ($LL.Count -eq 0)
    $Last = [DateTime]0
    Else
    $Last = [DateTime]$LL.Item(0)
    If ($Last -eq 0)
    $LastLogon = $Last.AddYears(1600)
    Else
    $LastLogon = $Last.AddYears(1600).ToLocalTime()
    If ($arrUsers.ContainsKey("$DN"))
    If ($LastLogon -gt $arrUsers["$DN"])
    $arrUsers["$DN"] = $LastLogon
    Else
    $arrUsers.Add("$DN", $LastLogon)
    # Output latest last logon date for each user.
    $Users = $arrUsers.Keys
    ForEach ($DN In $Users)
    $Date = $arrUsers["$DN"]
    "$DN;$Date"

    It is part of the userAccountControl attribute. Retrieve that attribute for each user and test if the ADS_UF_ACCOUNTDISABLE bit (2) is set.
    -- Bill Stewart [Bill_Stewart]

  • Different Results with Powershel v2 and v3

    Hope someone can help me determine why there is a difference in my data between v2 and v3 of Powershell. I do my development on my laptop which has version 3 installed, but the script is executed on a server which has version 2 installed.
    #create directory searcher object and set it's porperties
    $searcher = New-Object DirectoryServices.DirectorySearcher
    # (!userAccountControl:1.2.840.113556.1.4.803:=2) - Filters out disabled accounts
    $searcher.Filter = '(&(objectCategory=person)(objectClass=user)(!samaccountname=ITS-*)(!userAccountControl:1.2.840.113556.1.4.803:=2))'
    $searcher.PageSize = 5
    $searcher.SearchRoot = "LDAP://OU=District Offices,DC=myDomain,DC=com"
    #load only the following properties
    $params = @("samaccountname","sn","givenname","mail","physicaldeliveryofficename","department","title","manager","distinguishedname")
    foreach($param in $params)
    $searcher.PropertiesToLoad.Add($param) | Out-Null
    try
    $found = $searcher.FindAll()
    $found | ForEach-Object {
    if (($_.Properties["distinguishedname"] -notlike "*,OU=Generic User Accounts*") -and ($_.Properties["title"] -notlike "*Consultant*") `
    -and ($_.Properties["title"] -notlike "*Commissioner*") -and ($_.Properties["title"] -notlike "*Security Guard*") `
    -and ($_.Properties["title"] -notlike "*OSC*") -and ($_.Properties["title"] -notlike "*DCC*Temp*") -and ($_.Properties["samaccountname"] -ne "tbjohn") `
    -and (($_.Properties["mail"] -ne "")))
    $filtered += $_
    Running this script on my machine produces the data that the user is looking for. When I run it on the server, there are users in the data file that should not be. In the filter statement if I change
    -and (($_.Properties["mail"] -ne "")))
    #TO BE
    -and (($_.Properties["mail"] -ne $null)))
    Then those users are removed, but then other users are included and I haven't figured out why yet. Why would there be a difference, with the above script? I would think that should work in any version but obviously that is not true.
    If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.
    Don't Retire Technet

    jrv, with your modifications, things look to be going great, but again I am having an issue between version 3 and version 2 of powershell
    I have the following code in a file
    $searcher = New-Object DirectoryServices.DirectorySearcher
    $searcher.Filter = '(&(objectCategory=person)(objectClass=user)(mail=*)(!samaccountname=ITS-*)(!userAccountControl:1.2.840.113556.1.4.803:=2))'
    $searcher.PageSize = 5
    $searcher.SearchRoot = "LDAP://OU=District Offices,DC=MyDomain,DC=com"
    #load only the following properties
    $params = @("samaccountname","sn","givenname","mail","physicaldeliveryofficename","department","title","manager","distinguishedname")
    foreach($param in $params)
    $searcher.PropertiesToLoad.Add($param) | Out-Null
    # Filtered results to exclude certain OU's
    $filtered = @()
    try
    $filtered += $searcher.FindAll() | Where {
    $_.Properties["distinguishedname"][0] -notmatch ",OU=Generic User Accounts" `
    -and $_.Properties["title"][0] -notmatch "Consultant|Commissioner|Security Guard|OCS|DCC.*Temp" `
    -and $_.Properties["samaccountname"][0] -ne "tbjohn"
    $filtered.Count
    catch
    Write-Host "Error occured $_"
    exit
    I then did two different tests. In a command window I run the following
    C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe -Version 3.0 -ExecutionPolicy RemoteSigned -File F:\PS_Scripts\ADTest.ps1
    The results here return the count of 2485, yet if I force it to use version two with the following command
    C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe -Version 2.0 -ExecutionPolicy RemoteSigned -File F:\PS_Scripts\ADTest.ps1
    The results returned is an error stating "Cannot index into a null array", is there a difference in the DirectorySearcher object in version 2.0 compared to version 3.0?
    If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.
    Don't Retire Technet

  • How to rename computer account using Powershell 2.0

    Hi,
    For my Win7 deployment environment i need a script that can rename my workstation and it's Active Directory computer account.
    Is this possible using Powershell 2.0 included in Win7?

    I created a PowerShell script that, among other things, renames the computer.
    Function Rename-Computer ([string]$NewComputerName) {
    $comp = (gwmi win32_computersystem).Name.Trim()
    $ComputerInfo = Get-WmiObject -Class Win32_ComputerSystem
    Write-Host "Renaming computer...`n`tOld name: $comp`n`tNew name: $apnewname"
    #Start-Sleep (10)
    $ComputerInfo.rename($NewComputerName) | Out-Null
    After that you should reboot
    function RestartMachine{
    $os = gwmi win32_operatingsystem
    $os.psbase.Scope.Options.EnablePrivileges = $True
    $os.Reboot()
    Or better yet just use the `Restart-Computer` cmdlet built into PoSH.
    Now, the original post also said there was a need to rename the computer object n AD.  Below are two functions I use primarily for moving AD objects into their appropriate OU home.  While that doesn't immediately answer the question or solve the
    problem, I do believe you can rename the object you bind to using a very similar method.
    # This was created with the idea that machines would join the
    # domain automatically, into a predetermined OU. From there,
    # we would determine which OU the machine should be in, then
    # move it by calling this function.
    function MoveOU ($newOU) {
    $comp = (gwmi win32_computersystem).Name.Trim()
    $dumpOU = "CN=Computers,"
    # DC=dc,DC=net
    $root = [adsi]""
    #CN=Computers,DC=dc,DC=net
    $srcOU = [adsi]("LDAP://"+$dumpOU+$root.distinguishedName)
    #OU=fixedOU,OU=testOU,DC=dc,DC=net
    $destOU = [adsi]("LDAP://OU=fixedOU,OU=testOU,"+$root.distinguishedName)
    #CN=COMPUTERNAME,CN=Computers,DC=dc,DC=net
    $admin = [adsi]("LDAP://CN="+$comp+","+$srcOU.distinguishedName)
    #$admin.psbase | get-member | where-object {$_.Name -eq "MoveTo"}
    #System.Void MoveTo(DirectoryEntry newParent), System.Void MoveTo(DirectoryEntry newParent, String newName)
    $admin.PSBase.MoveTo($destOU)
    Function Move-OU ($SiteDC, $newOU) {
    $computerName = (gwmi win32_computersystem).Name.Trim()
    $_computerType = "CN=Computer,CN=Schema,CN=Configuration,DC=dc,DC=net"
    $path = "LDAP://$SiteDC/DC=dc,DC=net"
    $domain = "domain"
    $user = "user"
    $pass = "password"
    $de = New-Object System.DirectoryServices.DirectoryEntry($path,"$domain\$user",$pass)
    $ds = New-Object System.DirectoryServices.DirectorySearcher($de)
    $ds.Filter = "(&(ObjectCategory=computer)(samaccountname=$computerName$))"
    $res = $ds.FindAll()
    if ($res.count -gt 0) {
    # Machine has been found
    # Bind to the Computer Object in AD
    $oldComputerObject = New-Object System.DirectoryServices.DirectoryEntry($res[0].path,"$domain\$user",$pass)
    #$oldOU = $oldComputerObject.distinguishedName
    $oldOU = $oldComputerObject.Path
    Else {
    $strFilter = "(Name=$computerName)"
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$SiteDC/dc=dc,dc=net","$domain\$user",$pass)
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher($objdomain)
    $objSearcher.SearchRoot = $objDomain
    $objSearcher.PageSize = 1000
    $objSearcher.Filter = $strFilter
    $objSearcher.SearchScope = "Subtree"
    $colPropList = "distinguishedName", "Name"
    foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i) | Out-Null}
    $colResults = $objSearcher.FindAll()
    #$colResults.Count
    if($colResults.count -gt 0) {
    foreach($result in $colResults) { $target = $result.Properties }
    $Error.Clear()
    #$oldOU = $target.distinguishedname
    $oldOU = [string]$target.adspath
    Else {
    write-host "`tWARNING: Unable to locate $computername in AD; Cannot move to correct OU"
    ErrorLog "WARNING: Cannot move object $computername to correct OU; Not found in AD."
    $destOU = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$SiteDC/$newOU","$domain\$user",$pass)
    $oldComputerObject.PSBase.MoveTo($destOU)
    /\/\o\/\/ who has been known to dabble in scripting a bit (;) has also covered this subject here.  I would copy & paste, but I highly recommend reading it to get a better understanding of what's going on.  Plus, there's LOADS of useful information
    on that site!
    http://mow001.blogspot.com/2006/09/powershell-active-directory-part-11.html

  • Re : Powershell does NOT return errorcode to CMD file thats invoking PS

    Hello there,
    I am trying to return the exit code from PS back to CMD file that invokes the PS. Funny thing is PS does print exit code as 1 but CMD files still shows errorlevel as 0..... not sure what is causing it. The catch block in PS , I attempted to make generic
    and seems catch the exception correctly and is also printing the errorcode as 1 in PS. but upon exit 1 in PS , CMD file still shows %ERRORCODE% as 0 !
    Appreciate suggestions on this.
    CMD File
    :DBLOGIN
    CALL login.cmd username
    if %errorlevel% == 1 goto badend
    SET PWORD=%PASS_WORD%
    :ADLOGIN
    CALL AD_login.cmd %5
    if %errorlevel% == 1 goto badend
    SET AD_PWORD=%AD_PASS_WORD%
    SET PS_DIR=%1
    SET ROOT_DIR=%2
    SET UNAME=%3
    SET CONNSTR=%4
    SET ELE_UNAME=%5
    SET GROUPNAME=%6
    SET GROUPDOMAINNAME=%7
    SET DIR=%8
    d:
    cd %ROOT_DIR%
    %PS_DIR% -File "%ROOT_DIR%\adsync.ps1" %UNAME% %PWORD% %CONNSTR% %ELE_UNAME% %AD_PWORD% %GROUPNAME% %GROUPDOMAINNAME% %DIR% 2>&1 | more
    echo error level is %ERRORLEVEL%
    if %ERRORLEVEL% NEQ 0 GOTO badend
    GOTO ENDPROC
    :badend
    REM BAD END %ERRORLEVEL%
    @ECHO OFF & ECHO. & DATE /T & TIME /T & ECHO. & @ECHO ON
    exit /B 55
    :ENDPROC
    REM ACCEPTABLE RETURN CODE FOUND
    REM Error Level - %ERRORLEVEL%
    @ECHO OFF & ECHO. & DATE /T & TIME /T & ECHO. & @ECHO ON
    EXIT /B 0
    The powershell code is : 
    Import-Module ActiveDirectory
    $returncode =0;
    try
    $forestName = ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).Name
    $ADsPath = [ADSI]"GC://$forestName"
    $Search = New-Object System.DirectoryServices.DirectorySearcher($ADsPath)
    $OraClientDir=$args[7];
    echo $OraClientDir;
    [Reflection.Assembly]::LoadFile("$($OraClientDir)Oracle.DataAccess.dll")
    $DBUserName=$args[0];
    $DBPassword=$args[1];
    $DBSourceName=$args[2];
    $eleuser=$args[3];
    echo $eleuser;
    $elepword=ConvertTo-SecureString -String $args[4] -AsPlainText -Force;
    echo $elepword;
    $Credentials=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $eleuser,$elepword;
    echo $Credentials;
    $ADGroupName=$args[5];
    echo $ADGroupName;
    $ADGroupServerName=$args[6];
    echo $ADGroupServerName;
    $ADGroupServerString="$($ADGroupName) -server ""$($ADGroupServerName)""" ;
    echo $ADGroupServerString;
    Write-Host \n;
    echo " Start time is : $(Get-Date -format "yyyy:MM:dd hh:mm:ss:tt") ";
    $con=New-Object Oracle.DataAccess.Client.OracleConnection("Data Source=$DBSourceName;User Id=$DBUserName;Password=$DBPassword")
    $con.open()
    $cmd=$con.CreateCommand()
    $cmd.CommandText="SELECT blah blah SQL"
    $rdr=$cmd.ExecuteReader()
    $found= $false;
    $counter=0;
    $counterNew=0;
    $group=Get-ADGroup $ADGroupName -server $ADGroupServerName;
    $members = @()
    Get-ADGroupMember -Identity $group | Select-Object -ExpandProperty sAMAccountName |ForEach-Object {$members += $_};
    $path="\logs\log_$(Get-Date -format yyyy_MM_dd_hh_mm_ss_tt).log";
    Write-Host "The total members in group " $group " are " $members.length;
    Add-Content -Path $path -Value ("The total members in group " + $group + " are " + $members.length ) -Force;
    while ($rdr.Read())
    for ($i=0;$i -lt $rdr.FieldCount ; $i++)
    $found= $false;
    $s=$rdr.GetValue($i);
    $Search.Filter = "(&(objectCategory=User)(SamAccountName=$s))"
    if ($Search.FindAll().Count -eq 0)
    Add-Content -Path $path -Value "The user $s does NOT exists in AD global catalog" -Force;
    Write-Host "The user : " $s "does NOT exists in AD global catalog" ;
    $counter++;
    else {
    try {
    foreach ($res in $Search.FindAll())
    $User = $res.GetDirectoryEntry();
    Add-Content -Path $path -Value ("The user " + $User.SamAccountName + " Found in AD global catalog") -Force;
    Write-Host "The user distinguished name is : " $User.DistinguishedName " Found in AD global catalog" ;
    $DC = $User.DistinguishedName.ToString();
    $DCString = $DC.SubString($DC.IndexOf("DC="));
    $FQDN = $DCString.replace("DC=","").replace(",",".");
    # Add-Content -Path $path -Value $FQDN -Force;
    $found = $true;
    if ( ($found) -and ($members -notcontains $s))
    $checkuser= Get-ADUser $User.SamAccountName.ToString() -Server $FQDN ;
    Add-ADGroupMember $group -Members $checkuser -Server $ADGroupServerName -Credential $Credentials;
    Add-Content -Path $path -Value ("Added user: " + $User.SamAccountName ) -Force ;
    Write-Host "Added user: " $User.SamAccountName;
    $counterNew++;
    } catch [Exception] {
    Write-Host $_.Exception.Message "is inner catch";
    $returncode =1;
    Add-Content -Path $path -Value "Total of : $counterNew users users have been added " -Force;
    Write-Host "Total of : $counterNew users users have been added to AD Group";
    Add-Content -Path $path -Value "Total of : $counter users do NOT exist in Windows AD global catalog";
    Write-Host "Total of : $counter users do NOT exist in Windows AD global catalog";
    catch [Exception] {
    Write-Host $_.Exception.Message "is outer catch";
    $returncode =1;
    Write-Host \n;
    echo " End time is : $(Get-Date -format "yyyy:MM:dd hh:mm:ss:tt") ";
    Write-Host "value of return code is " $returncode;
    exit $returncode;

    Maybe the webpages below can help someone compose a workaround
    https://connect.microsoft.com/PowerShell/feedback/details/750653/powershell-exe-doesn-t-return-correct-exit-codes-when-using-the-file-option
    https://connect.microsoft.com/PowerShell/feedback/details/750653/powershell-exe-doesn-t-return-correct-exit-codes-when-using-the-file-option#

  • Query/Enumerate eDirectory in Powershell via System.DirectoryServices

    Hello Scripting Guy,
        I have been tasked with taking a .Net program/project and converting it to PowerShell.  The .Net program exported three sources of information and inserts those exports into a SQL database for multiple functions and reasons. 
    The three sources are AD, eDirectory, and PeopleSoft.  The AD was simple with the "Module for Active Directory" and "SQLPS".  Now, I need to connect to eDirectory via LDAP and query the source.  I am able to connect/bind
    to the eDirectory and search but I need to enumerate the directory and insert that into a SQL table.  Given the logic I have developed for AD, it will be no problem inserting the records into SQL but I have not found anything to get my over the hurdle
    of enumerating the directory.  Below is the code that I found to successfully connect with eDirectory and perform a search.  Thank you.
    Connection Setup
    $eDir = New-Object System.DirectoryServices.Protocols.LdapDirectoryIdentifier('1.2.3.4','389')
    $eDirCreds = New-Object System.Net.NetworkCredential('cn=ConnectID,o=Home','MyConnectPS')
    $ED = New-Object System.DirectoryServices.Protocols.LdapConnection($eDir,$eDirCreds)
    $ED.SessionOptions.SecureSocketLayer = $False
    $ED.AuthType = 'Basic'
    $ED.Bind();
    Search eDirectory records
    $SearchScope = [System.DirectoryServices.Protocols.SearchScope]::SubTree
    $SearchAttributeList = ,"*" <--- Not quit sure why the "," proceeds the "*"
    $SearchBaseDN = "o=Home"
    $SearchFilter = "(uid=SomeUser)"
    $SearchReq = new-object System.DirectoryServices.Protocols.SearchRequest -ArgumentList $SearchBaseDN,$SearchFilter,$SearchScope,$SearchAttributeList
    $SR = $ED.SendRequest($SearchReq)
        $SR displays ResultCode of success found or not found but if found contains DN in the "Entries" field.
    MatchedDN    :
    Controls     : {}
    ResultCode   : Success
    ErrorMessage :
    Referral     : {}
    References   : {}
    Entries      : {cn=MyID,ou=OU1,ou=OU2,o=Home}
    RequestId    :

    I found my answer via this link at the Script Library:
    ---http://www.thescriptlibrary.com/Default.asp?Action=Display&Level=Category3&ScriptLanguage=Powershell&Category1=Active%20Directory&Category2=User%20Accounts&Title=Scripting%20Ldap%20Searches%20using%20PowerShell---
    In answer to your question JRV, I wanted to perform a LDAP query for all directory ENTRIES in the eDirectory LDAP and then process the results into a SQL destination.  The LDAP search that I was successful with only returned the success or fail
    of finding a single object that I search for not the entire LDAP directory.
    There was also an unanswered post from 2007 under the subject of "querying Edirectory using System.DirectoryServices.Protocols" that I was referred to when I filled the subject to this question.  It went unanswered
    and acknowledged for two years.
    Here is the code and a small sample of data so that it may help others.  The GetType() for $SearchResults returns as a System.Array with a sub System.Array as the Properties column.  Also code to handle the results.
    #Load Support Modules and Assemblies
    Import-Module ActiveDirectory
    Import-Module SQLPS -DisableNameChecking
    Add-Type -AssemblyName System.DirectoryServices
    #Setup eDirectory Connection Variables
    $eDirPath = 'LDAP://1.1.1.1:389/o=home' (Whatever the eDir)
    $eDirUser = 'cn=MyLDAPID,o=Home' (DN of UID)
    $eDirPWD = 'MyLDAPPWD'
    $eDIrAuthType = 'None' (Equates to basic)
    #Establish eDirectory Connection and Enumerate
    $Root = New-Object System.DirectoryServices.DirectoryEntry -argumentlist $eDirPath,$eDirUser,$eDirPWD,$eDIrAuthType
    $Query = New-Object System.DirectoryServices.DirectorySearcher
    $Query.SearchRoot = $Root
    $Query.Filter = "(ObjectClass=Person)" (or whatever LDAP query you want)
    $SearchResults = $Query.FindAll()
    Path Properties
    LDAP://1.1.1.1:389/cn=Account1,o=home {loginshell, telephonenumber, uniqueid, securityequals...}
    LDAP://1.1.1.1:389/cn=Account2,o=home {loginshell, telephonenumber, uniqueid, securityequals...}
    LDAP://1.1.1.1:389/cn=Account3,o=home {loginshell, uniqueid, securityequals, gidnumber...}
    #For processing each entry in the results
    ForEach ($Result in $SearchResults) `
    #Convert object to utilize named values like CN, SN, UniqueID
    $eDirObject = [PSCustomObject]$Result.Properties
    write-host "$eDirObject.cn $eDirObject.sn $eDirObject.UniqueID"

  • "Welcome to the Task Sequence Wizard" never shows on PXE boot, but does on Boot Media with prestart command

    Hey guys, I have a fairly odd situation here.  I have all OSD Task Sequence advertisements set to "PXE and Boot Media (hidden)" and all are optional
    (not mandatory).  I use a powershell form via prestart command to give the user a choice which limits what task sequences they choose.  When everything is working, this process works.  Unknown desktop-class systems see desktop task sequences,
    and server-class systems see server task sequences.
    Here's where it's different when I use different boot methods:
    Boot Media
    "Welcome to the Task Sequence Wizard" is presented.  User hits or clicks Enter.
    Powershell form is presented; user picks their task sequence
    Confirmation screen is presented with the task sequence they selected (this is an OSD screen the same size as the "Welcome to the Task Sequence Wizard"
    screen.
    Dependency check screen is shown with a progress bar.  If a package is missing from a DP, it will display an error here with the PackageID.  This
    looks the same as "Regular" OSD with standard non-hidden advertisements.
    PXE Boot
    "Welcome to the Task Sequence Wizard" is never displayed.
    Powershell form is the first screen they see.  They select it and it continues.
    No confirmation screen is presented if the system is known;  if it is an unknown system, a small dialog says there is a
    *mandatory* task sequence about to be run and it will run in 180 seconds.  Users can hit enter.
    No dependency check screen is shown; and if a package was missing, instead of presenting an error, it simply reboots.  However, if everything is there,
    the process starts successfully.
    While I have no problems with the first window never being displayed, not displaying the error dialog and simply rebooting is what is bothersome to me. 
    99% of our builds are from PXE boot.
    Again, these task sequences are all 100% optional, NOT mandatory, and I've double checked this multiple times.  Can anyone explain why we get different
    behavior between boot media and PXE boot?  Any way of getting PXE boot to "mimic" the Boot media behavior?
    I followed the guide here:
    http://www.mydreampage.net/2012/09/21/how-can-i-deploy-a-hidden-task-sequence-in-configuration-manager-2012-sp1/
    If you see the image here:
    http://www.windows-noob.com/forums/uploads/monthly_09_2012/post-1-0-29840100-1348236179.png
    You'll see the "Retrieving policy for this computer..." dialog box - I never get that with PXE - just Boot Media.
    Note that I am running 2012 R2, not 2012 SP1 - but I never got a chance to test this process with SP1.
    Upon further experimentation, the "hidden" task sequence has nothing to do with this.  If I change it to a normal, non-hidden advertisement, as
    long as the "prestart" command in the boot image is used, we don't get those missing dialog boxes at all, with PXE.

    Are both boot images the same for PXE and the boot media? Same package ID and all? 
    Boot media for us always shows the task sequence wizard first, while PXE always displays the pre-start command first. 
    Daniel Ratliff | http://www.PotentEngineer.com

  • Powershell script Information output in column instead of rows

    Dear All,
    I am required powershell script Information output  in column instead of rows.
    $usr= get-aduser -filter * | select sAMAccountName,homeDrive,TerminalServicesProfilePath,homeDirectory,physicalDeliveryOfficeName,userAccountControl,displayName,l,mail, profilepath
    $myarray = @()
    Foreach($usr1 in $usr)
    $userDN = (Get-ADUser $usr1.samaccountname).distinguishedName
    $userInfo = [ADSI]"LDAP://$userDN" | select sAMAccountName,homeDrive,TerminalServicesProfilePath,homeDirectory,physicalDeliveryOfficeName,userAccountControl,displayName,l,mail, profilepath
    $ts=$userInfo.TerminalServicesProfilePath
    $sn=$userInfo.samaccountname
    $hm=$userinfo.homeDrive
    $hd=$userinfo.homeDirectory
    $pd=$userinfo.physicalDeliveryOfficeName
    $ua=$userinfo.userAccountControl
    $dp=$userinfo.displayName
    $ll=$userinfo.l
    $ml=$userinfo.mail
    $pp=$userinfo.profilepath
    $myarray += New-Object psobject -Property @{
        Sam = $userInfo.samaccountname
        TerminalServicesProfilePath = $userInfo.TerminalServicesProfilePath
      homeDrive = $userinfo.homeDrive
        homeDirectory=$userinfo.homeDirectory
        physicalDeliveryOfficeName=$userinfo.physicalDeliveryOfficeName
        userAccountControl=$userinfo.userAccountControl
        displayName=$userinfo.displayName
         l=$userinfo.l
         mail=$userinfo.mail
         profilepath=$userinfo.profilepath
    $myarray |fl
    $myarray | Out-File "c:\final.txt"

    Hey this is such a sweet small script compared to everything else out there and I guess you can edit it to return any value you wish. One LARGE problem however: the TerminalServicesProfilePath comes back empty on all accounts regardless of whether the field
    is populated or not. This is basically because this setting is not stored in an Active Directory attribute but Terminal Services information is stored in the userParameters schema attribute as a BLOB.
    I got this script:
    $Users = ([ADSISearcher]"(&(objectCategory=person)(objectClass=user))").findall() | select path
    foreach ($user in $users) {
    $userSearch = [adsi]"$($user.path)"
    # get logon name
    $userSearch.psbase.InvokeGet(“SamAccountName”)
    # Profile Attributes
    $userSearch.psbase.InvokeGet("ProfilePath")
    # Remote Desktop Services Attributes
    $userSearch.psbase.InvokeGet("TerminalServicesProfilePath")
    which returns the value but the output is terribly unformatted. If we could integrate the two to ensure that it is correctly formatted, AND returns the TSProfile that would be awesome!
    Can anyone help me do that?
    Life is dangerous, no one has ever survived. So enjoy!
    Please do not tag an unrelated quesiton onto the end of an old and answered question.  Please read the forum guidelines before posting.
    We do not do custom scripts on demand.
    ¯\_(ツ)_/¯

  • Query AD cause Exception calling "FindAll" with "0" argument(s)

    Hi all,
    When I query an entry property of AD with PowerShell, i got some problems. Here is the script, what's wrong ? Any idea? Thanks!
    Cause error at last line code. (Exception calling "FindAll" with "0" argument(s): "There is no such object on the server)
    $MailboxServer = Get-MailboxServer -Identity $Env:COMPUTERNAME -ErrorAction SilentlyContinue
    $dc = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $exchOAB = New-Object System.DirectoryServices.DirectoryEntry("LDAP://" + $dc.Name + "/cn=Offline Address Lists,cn=Address Lists Container, " + $MailboxServer.DistinguishedName)
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $exchOAB
    $objSearcher.PageSize = 1000
    $objSearcher.SearchScope = "OneLevel"
    $objSearcher.Filter = "(objectClass=msExchOAB)"
    $powershellOAB = $objSearcher.FindAll()

    This is one of, now, four duplicate posts.
    ¯\_(ツ)_/¯

  • Powershell Name Change with If else not working as expected

    The script we've written below executes the if statement correctly and changes the name properly though the else condition is not working properly.  The example data file we  use for input is shown below and it's name is namechanges.csv
    Test,User,User1,1111,2222,[email protected]
    Test,Smith,User2,2222,3333,[email protected]
    Test,Jones,User3,3333,4444,[email protected]
    Test,Doe,User4,4444,5555,[email protected]
    Test,Example,User5,5555,7777,[email protected]
    The script shown below changes the name in Active Directory, home directory, and Exchange to a unique username and new last name (eg. maiden name needs changed to married name)
    $ADRoot = [ADSI]''
    $ADSearch = New-Object System.DirectoryServices.DirectorySearcher($ADRoot)
    add-PSSnapIn -name Microsoft.Exchange.Management.PowerShell.Admin
    Import-module ActiveDirectory
    Get-Content C:\New_Account\namechanges.csv |
    ForEach {
        $Fname = ($_ -split ',')[0]
        $nLname = ($_ -split ',')[1]
        $lname = ($_ -split ',')[2]
        $NUM = ($_ -split ',')[3]
        $ID = ($_ -split ',')[4]
        $requestor = ($_ -split ',')[5]
     $Counter = 0
    $Emp = Get-aduser -Filter {(employeeID -eq $ID)-and (EmployeeNumber -eq $NUM)}
    $SamAccount = (get-aduser -Filter {employeeID -eq $ID }).SamAccountName
    $SamAccount
    $FNAME = (get-aduser -Filter {employeeID -eq $ID }).GivenName
    $FNAME
    $LNAME = (get-aduser -Filter {employeeID -eq $ID }).Surname
    $LNAME
    $UserPrincipalName = (get-aduser -Filter {employeeID -eq $ID }).UserPrincipalName
    $UserPrincipalName
    Start-Sleep 2
    Set-ADUser $SamAccount -surname $nlname -DisplayName $FNAME" "$nlname
    Start-Sleep 2
    if ($Emp -ne $null)
          $Counter = 1
       $Counter
          Do
         $F = $Fname.remove($Counter)
         $newusername = $F + $nLname
         $ADSearch.Filter = "(&(objectClass=user)(sAMAccountName=$newusername))"
         $Result = $ADSearch.FindAll()
         $t = $result.Count          
                   if ($t -lt 1)
          $FoundUniqueUserName = $True
             Else
          $Counter = $Counter + 1
          $FoundUniqueUserName = $False
       While ($FoundUniqueUserName -eq $False)  
       $newusername 
    Start-Sleep 2
    rename-adobject -identity ((get-aduser $Emp).ObjectGUID) -NewName "$Fname $nLname"
    Start-Sleep 2
    Rename-Item \\secret.com\share\home\$SamAccount $newusername
    Start-Sleep 2
    Set-ADUser $SamAccount -surname $nlname -DisplayName $Fname" "$nlname
    Start-Sleep 2
    $newUPN = $newusername + "@secret.com"
    Start-Sleep 2
    Set-ADUser $SamAccount -SamAccountName $newusername -UserPrincipalName $newUPN
    Start-Sleep 5
    $Mailbox = Get-Mailbox -Identity $SamAccount
    $SMTPAddress = $Mailbox.PrimarySmtpAddress
    $Domain = $SMTPAddress.Domain
    Start-Sleep 5
    $emailaddress = "$newusername@$Domain"
    Start-Sleep 5
    Set-Mailbox $SamAccount -EmailAddressPolicyEnabled:$False -PrimarySmtpAddress $emailaddress -Alias $newusername
    Start-Sleep 5
    Set-Mailbox $emailaddress -EmailAddressPolicyEnabled:$true
    Start-Sleep 5
         $smtpServer = "mail.secret.com"
         $msg = new-object Net.Mail.MailMessage
         $smtp = new-object Net.Mail.SmtpClient($smtpServer)
         $msg.From = "[email protected]"
         $msg.To.Add($requestor)
         $msg.subject = "A name change request for $FNAME $LNAME was succesfull"
         $msg.body = "A name change request for $FNAME $LNAME was succesfull"
         $smtp.Send($msg)  
    Start-Sleep 8
    Else
         $smtpServer = "mail.secret.com"
         $msg = new-object Net.Mail.MailMessage
         $smtp = new-object Net.Mail.SmtpClient($smtpServer)
         $msg.From = "[email protected]"
         $msg.To.Add($requestor)
         $msg.subject = "A Name change request was received but the script failed to make the change."
         $msg.body = "A name change request for $FNAME $LNAME was requested with the employee id and number of $ID and $NUM. The request was not succesfull"
         $smtp.Send($msg)   
    Out-File C:\New_Account\name_change_log.txt -InputObject "At $([datetime]::now) there was a name change request for $Fname $lname-$nLname with ID of $ID and number of $NUM." -Append
    Start-Sleep 5
    #Remove-Item C:\New_Account\namechanges.csv
    Else {
    "Something went wrong"
    Can someone take a look at the code and see where I went wrong with the else statement?  Let's say hypothetically Test Smith is a common name and already exists in Active Directory in the same OU we attempt to make the username unique however if that
    fails I would like to receive the email and  update the name change in some other way.

    Well the code you presented has two issues that I can see
    You have the following
    While ($FoundUniqueUserName -eq $False)
    $newusername
    Start-Sleep 2
    rename-adobject -identity ((get-aduser $Emp).ObjectGUID) -NewName "$Fname $nLname"
    Start-Sleep 2
    Rename-Item \\secret.com\share\home\$SamAccount $newusername
    Start-Sleep 2
    Set-ADUser $SamAccount -surname $nlname -DisplayName $Fname" "$nlname
    Start-Sleep 2
    $newUPN = $newusername + "@secret.com"
    Start-Sleep 2
    Set-ADUser $SamAccount -SamAccountName $newusername -UserPrincipalName $newUPN
    Start-Sleep 5
    $Mailbox = Get-Mailbox -Identity $SamAccount
    $SMTPAddress = $Mailbox.PrimarySmtpAddress
    $Domain = $SMTPAddress.Domain
    Start-Sleep 5
    $emailaddress = "$newusername@$Domain"
    Start-Sleep 5
    Set-Mailbox $SamAccount -EmailAddressPolicyEnabled:$False -PrimarySmtpAddress $emailaddress -Alias $newusername
    Start-Sleep 5
    Set-Mailbox $emailaddress -EmailAddressPolicyEnabled:$true
    Start-Sleep 5
    $smtpServer = "mail.secret.com"
    $msg = new-object Net.Mail.MailMessage
    $smtp = new-object Net.Mail.SmtpClient($smtpServer)
    $msg.From = "[email protected]"
    $msg.To.Add($requestor)
    $msg.subject = "A name change request for $FNAME $LNAME was succesfull"
    $msg.body = "A name change request for $FNAME $LNAME was succesfull"
    $smtp.Send($msg)
    Start-Sleep 8
    Which has no open and closing brackets for the while loop, then at the end of the script you have
    #Remove-Item C:\New_Account\namechanges.csv
    Else
    "Something went wrong"
    That else has no opening If statement.....I would fix these issues first, straighten your code out a bit and see if it works then, as the no opening and closing brackets on the While loop and the extra else statement, may be giving you some issues.
    If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.
    Don't Retire Technet

  • How to add "Computer Description" locally to 300 Servers in our domain via PowerShell.

    I'd like to use Powershell to add "Computer Description" locally to 300 Servers in domain.
    I found a solution here which works but it adds "Computer Description" only to a single computer.
    http://social.technet.microsoft.com/Forums/windowsserver/en-US/a777f07c-f9be-4eb5-8788-de7e5c068411/changing-computer-descriptions-remotely-using-powershell?forum=winserverpowershell
    I do have a CSV file with two column headers "Server" and "Description" containing Computer Description for all 300 Servers. 
    I'm new to Powershell and would appreciate a step by step method.
    Thanks.
    st

    Hi Mike Laughlin,
    Your Script worked beautifully on most Servers.
    There were some Servers on which it did not work. It showed this error in red color:
    Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT:
    0x800706BA)
    At line:2 char:17
    +     $OSValues = Get-WmiObject -Class Win32_OperatingSystem -ComputerName
    $_.Serv ...
    +
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMExcept
       ion
        + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands
       .GetWmiObjectCommand
    Property 'Description' cannot be found on this object; make sure it exists and
    is settable.
    At line:3 char:5
    +     $OSValues.Description = $_.Description
    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : PropertyNotFound
    You cannot call a method on a null-valued expression.
    At line:4 char:5
    +     $OSValues.Put()
    +     ~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull
    Hi tommymaynard,
    Should I now try your Script ?

Maybe you are looking for