Hi guys, I have the following script that does the following: it takes a list of users from CSV files and searches for them in AD. If they exist, it displays them on the screen in cyan; if they don’t, it displays them in red.<\/p>\n
I’m doing this as practice for something bigger. But I already have my doubts and I want to share them with the community to see if I’m on the right track.<\/p>\n
function Test-ADUser {\n param([Parameter(Mandatory)][String]$CSUR)\n return (New-Object System.DirectoryServices.DirectorySearcher([ADSI]'LDAP://DC=corp,DC=r0,DC=com', \"(&(objectClass=user)(sAMAccountName=$CSUR))\")).FindOne()\n}\n\nfunction Test-LenCSV {\n param([Parameter(Mandatory)][String]$CSVPath)\n return (Import-Csv -Path $CSVPath -Header NotCount | Measure-Object).Count\n}\n\nfunction Get-LSIADCsvFiles {\n param([Parameter(Mandatory)][String]$Path)\n\n $csvFiles = @()\n $csvPath = Get-ChildItem -Path $Path -Depth 0 -Filter \"List_*\"\n\n \n ForEach ($csv in $csvPath) {\n $csvFiles += $csv.FullName\n }\n\n return $csvFiles\n}\n\nif (!(Test-NetConnection -ComputerName vdc0.corp.r0.com -Port 445).TcpTestSucceeded) {\n\n exit\n\n}\n\nif (!((Get-PSDrive -Name \"CSVShare\" -ErrorAction SilentlyContinue).Name)) {\n New-PSDrive -Name \"CSVShare\" -Root \"\\\\vdc0.corp.r0.com\\test\" -PSProvider \"FileSystem\"\n}\nelse {\n exit\n}\n\n$counter = Get-LSIADCsvFiles \"CSVShare:\\\"\n\nif ($counter.Count) {\n\n foreach ($count in $counter) {\n if ((Test-LenCSV($count)) -gt 60) {\n Remove-PSDrive -Name CSVShare -Confirm:$false\n exit\n }\n }\n\n foreach ($count in $counter) {\n\n Import-CSV -Path $count -Header HOBJ | Foreach-Object {\n\n if (Test-ADUser(($_.HOBJ -replace '[^\\x00-\\x7F]', '') -replace '\\s', '')) {\n\n Write-Host $_.HOBJ -ForegroundColor Cyan\n }\n else {\n Write-Host $_.HOBJ -ForegroundColor Red\n }\n }\n }\n}\nRemove-PSDrive -Name CSVShare -Confirm:$false\n<\/code><\/pre>\n
Advertisement
I describe the functions:<\/p>\n
Test-ADUser<\/strong>: Single parameter function which is a String, you have to pass the sAMAccountName from the CSV and it searches for it in my AD, it returns true or false.<\/p>\nTest-LenCSV<\/strong>:The only string parameter is the absolute path to the CSV and counts the number of lines it has.<\/p>\nGet-LSIADCsvFiles<\/strong>:The absolute path of the CSV is passed and it is placed in an array since it can see more than one file, filtered by LIST_*<\/p>\nFirst of all, I haven’t considered a logging function for the exits of the else statements yet. But that doesn’t worry me right now.<\/p>\n
In the first if statement, I run a connection test to the server where the CSVs are stored on port 445, which is the SMB port. If it’s not operational, the script ends.<\/p>\n
If it is, in the second if statement, I mount the shared resource in a PSDRIVE so I can access the files more easily later. If the PSDRIVE already exists, the script ends.<\/p>\n
I create a variable called $counter to store the CSV paths.<\/p>\n
In the first FOREACH statement, I call the function to count the number of lines in the CSVs. If it’s greater than 60, the script ends.<\/p>\n
The second FOREACH statement executes as many CSV files as we have. I call the test user function to see if it exists in my AD, and it displays them on the screen. Finally we disassemble the PSDRIVE and finish the script.<\/p>\n
Right now I have the following questions:<\/p>\n
\n- The Get-LSIADCsvFiles function is well designed, is there any better method to pass a list of files?
\n2.When I do the … you can see that I eliminate all the BYTES that do not belong to ASCII values since the CSVs I have are “dirty” I show a capture of a line.<\/li>\n<\/ol>\n
<\/p>\n
As you can see it starts with values 0XFF, 0XFE and the name is separated by NULL values, in reality the user line is: 43434256715K<\/strong> Apparently, Import-CSV isn’t affected by that “dirt,” and the -replace commands in the import are unnecessary. Is that true? I haven’t encountered any errors.<\/p>\nFinally, would you suggest any improvements?<\/p>\n
Thanks.<\/p>","upvoteCount":2,"answerCount":3,"datePublished":"2025-05-14T20:57:19.258Z","author":{"@type":"Person","name":"spiceuser-eassw","url":"https://community.spiceworks.com/u/spiceuser-eassw"},"acceptedAnswer":{"@type":"Answer","text":"
The FF and FE are Unicode byte order mark (BOM). As far as I know, only Windows systems care about it. If you use PowerShell 7, everything defaults to UTF8 with no BOM. The extra 00 bytes is also because of Unicode 16-bit encoding. Most of your characters fit in the ASCII range and only require one byte. Therefore the other byte is just empty. You just need to convert to a different encoding and not bother with all that manual cleansing if the BOM and extra 0s bother you.<\/p>\n
I want to believe that Windows PowerShell Import-CSV detects the encoding because of the BOM and therefore has no issues reading the file. Without the BOM, it will default to UTF8 or whatever encoding you explicitly pass to -Encoding. So if you decided to remove the BOM, import-CSV would read the file with UTF8 encoding.<\/p>\n
Honestly, I’d find the source of the CSV file creation and fix the encoding during that process to be what you want. If the files were created by PowerShell, they were likely created with Out-File (or its aliases > or >>) because that defaults to Unicode (LE). If you decided to move this process to PowerShell 7, I think you could have data issues<\/p>","upvoteCount":0,"datePublished":"2025-05-15T01:53:34.546Z","url":"https://community.spiceworks.com/t/powershell-import-csv-user-script/1205873/2","author":{"@type":"Person","name":"adminofthings","url":"https://community.spiceworks.com/u/adminofthings"}},"suggestedAnswer":[{"@type":"Answer","text":"
Hi guys, I have the following script that does the following: it takes a list of users from CSV files and searches for them in AD. If they exist, it displays them on the screen in cyan; if they don’t, it displays them in red.<\/p>\n
I’m doing this as practice for something bigger. But I already have my doubts and I want to share them with the community to see if I’m on the right track.<\/p>\n
function Test-ADUser {\n param([Parameter(Mandatory)][String]$CSUR)\n return (New-Object System.DirectoryServices.DirectorySearcher([ADSI]'LDAP://DC=corp,DC=r0,DC=com', \"(&(objectClass=user)(sAMAccountName=$CSUR))\")).FindOne()\n}\n\nfunction Test-LenCSV {\n param([Parameter(Mandatory)][String]$CSVPath)\n return (Import-Csv -Path $CSVPath -Header NotCount | Measure-Object).Count\n}\n\nfunction Get-LSIADCsvFiles {\n param([Parameter(Mandatory)][String]$Path)\n\n $csvFiles = @()\n $csvPath = Get-ChildItem -Path $Path -Depth 0 -Filter \"List_*\"\n\n \n ForEach ($csv in $csvPath) {\n $csvFiles += $csv.FullName\n }\n\n return $csvFiles\n}\n\nif (!(Test-NetConnection -ComputerName vdc0.corp.r0.com -Port 445).TcpTestSucceeded) {\n\n exit\n\n}\n\nif (!((Get-PSDrive -Name \"CSVShare\" -ErrorAction SilentlyContinue).Name)) {\n New-PSDrive -Name \"CSVShare\" -Root \"\\\\vdc0.corp.r0.com\\test\" -PSProvider \"FileSystem\"\n}\nelse {\n exit\n}\n\n$counter = Get-LSIADCsvFiles \"CSVShare:\\\"\n\nif ($counter.Count) {\n\n foreach ($count in $counter) {\n if ((Test-LenCSV($count)) -gt 60) {\n Remove-PSDrive -Name CSVShare -Confirm:$false\n exit\n }\n }\n\n foreach ($count in $counter) {\n\n Import-CSV -Path $count -Header HOBJ | Foreach-Object {\n\n if (Test-ADUser(($_.HOBJ -replace '[^\\x00-\\x7F]', '') -replace '\\s', '')) {\n\n Write-Host $_.HOBJ -ForegroundColor Cyan\n }\n else {\n Write-Host $_.HOBJ -ForegroundColor Red\n }\n }\n }\n}\nRemove-PSDrive -Name CSVShare -Confirm:$false\n<\/code><\/pre>\nI describe the functions:<\/p>\n
Test-ADUser<\/strong>: Single parameter function which is a String, you have to pass the sAMAccountName from the CSV and it searches for it in my AD, it returns true or false.<\/p>\nTest-LenCSV<\/strong>:The only string parameter is the absolute path to the CSV and counts the number of lines it has.<\/p>\nGet-LSIADCsvFiles<\/strong>:The absolute path of the CSV is passed and it is placed in an array since it can see more than one file, filtered by LIST_*<\/p>\nFirst of all, I haven’t considered a logging function for the exits of the else statements yet. But that doesn’t worry me right now.<\/p>\n
In the first if statement, I run a connection test to the server where the CSVs are stored on port 445, which is the SMB port. If it’s not operational, the script ends.<\/p>\n
If it is, in the second if statement, I mount the shared resource in a PSDRIVE so I can access the files more easily later. If the PSDRIVE already exists, the script ends.<\/p>\n
I create a variable called $counter to store the CSV paths.<\/p>\n
In the first FOREACH statement, I call the function to count the number of lines in the CSVs. If it’s greater than 60, the script ends.<\/p>\n
The second FOREACH statement executes as many CSV files as we have. I call the test user function to see if it exists in my AD, and it displays them on the screen. Finally we disassemble the PSDRIVE and finish the script.<\/p>\n
Right now I have the following questions:<\/p>\n
\n- The Get-LSIADCsvFiles function is well designed, is there any better method to pass a list of files?
\n2.When I do the … you can see that I eliminate all the BYTES that do not belong to ASCII values since the CSVs I have are “dirty” I show a capture of a line.<\/li>\n<\/ol>\n
<\/p>\n
As you can see it starts with values 0XFF, 0XFE and the name is separated by NULL values, in reality the user line is: 43434256715K<\/strong> Apparently, Import-CSV isn’t affected by that “dirt,” and the -replace commands in the import are unnecessary. Is that true? I haven’t encountered any errors.<\/p>\nFinally, would you suggest any improvements?<\/p>\n
Thanks.<\/p>","upvoteCount":2,"datePublished":"2025-05-14T20:57:19.329Z","url":"https://community.spiceworks.com/t/powershell-import-csv-user-script/1205873/1","author":{"@type":"Person","name":"spiceuser-eassw","url":"https://community.spiceworks.com/u/spiceuser-eassw"}},{"@type":"Answer","text":"
Thanks for the reply, everything worked correctly.<\/p>","upvoteCount":0,"datePublished":"2025-05-23T23:19:22.445Z","url":"https://community.spiceworks.com/t/powershell-import-csv-user-script/1205873/3","author":{"@type":"Person","name":"spiceuser-eassw","url":"https://community.spiceworks.com/u/spiceuser-eassw"}}]}}