Microsoft Graph issue - Filtering output - powershell

I'm exporting both custom and standard attributes of all users in Azure AD. I'm having difficulty wrapping my head around customizing the output when exporting.
For example, I'm seeking to export all users that are members, not Guests, with the below attributes:
$URI = "https://graph.microsoft.com/beta/users?`$select=displayName,userPrincipalName, mail, department, jobTitle, extension_1fe7973b28e74213b897d62528e614c7_extensionAttribute14, extension_1fe7973b28e74213b897d62528e614c7_extensionAttribute15, accountEnabled, signInActivity, UserType, id&`$expand=manager(`$select=displayName,userPrincipalName)&`$top=999"
I've tried adding to the URI above to include $filter=userType eq 'Guest'
I've tried adjusting my report object to
$ReportLine = [PSCustomObject] #{
UserType = $filter=$User.UserType -eq "Member"}
I've also tried modifying my write output code with no success:
Write-Host "All done. " $Report.Count "accounts processed - output available in c:\Temp\ReportUserSignin.csv."
$Report | Sort DisplayName | Out-GridView
$Report | ?{$_.UserType -eq "Guest"}| Sort {$_.LastSignIn -as [DateTime]} -Descending | Format-Table DisplayName, LastSignIn, Email | Export-CSV -NoTypeInformation c:\Temp\ReportUserSignin.csv
The above two only results in True/False results of the user is a member or guest.
Can someone provide some insight as to what I'm missing here or even where the filter should be for the exported report? I greatly appreciate any and all advice! :)

Related

Working with a list of AD 'displayNames' in Powershell. How to indicate which users were not found?

I have written enough PS code to go through a list of displayNames (e.g "John Smith", "Taylor Hanson" - all stored on seperate lines of a txt file) to spit back enough data into another text file that can be used for mailmerge etc. Convincing thousands of employees to simply update Windows is like breaking stones! It has to be automatted to some degree...
Here is the code... the functions that let the user open a specific text file and later save are out of view...
$displayname = #()
$names = get-content $FileIN
foreach ($name in $names) {
$displaynamedetails = Get-ADUser -filter { DisplayName -eq $name } | Select Name, GivenName, Surname, UserPrincipalName
$displayname += $displaynamedetails
}
$displayname | Export-Csv -NoTypeInformation -path $fileOUT -Encoding UTF8
From time to time, a name might be spelled incorrectly in the list, or the employee may have left the organisation.
Is there any way that a statement such as 'Not Found' can be written to the specific line of the text file if an error is ever made (so that an easy side-by-side comparison of the two files can be made?
For most of the other solutions I've tried to find, the answers are based around the samAccoutName or merging the first and last names together. Here, i am specifically interested in displaynames.
Thanks
You can give this a try, since -Filter or -LDAPFilter don't throw any exception whenever an object couldn't be found (unless you're feeding a null value) you can add an if condition to check if the variable where the AD User object is going to be stored is not null and if it is you can add this "not found" user into a different array.
$domain = (Get-ADRootDSE).DefaultNamingContext
$names = Get-Content $FileIN
$refNotFound = [System.Collections.Generic.List[string]]::new()
$displaynamedetails = foreach($name in $names)
{
if($aduser = Get-ADUser -LDAPFilter "(DisplayName=$name)")
{
$aduser
continue
}
$refNotFound.Add(
"Cannot find an object with DisplayName: '$name' under: $domain"
)
}
$displaynamedetails | Select-Object Name, GivenName, Surname, UserPrincipalName |
Export-Csv -NoTypeInformation -path $fileOUT -Encoding UTF8
$refNotFound # => Here are the users that couldn't be found
Side note, consider stop using $displayname = #() and += for well known reasons.
As for AD Cmdlets, using scriptblock based filtering (-Filter {...}) is not supported and even though it can work, it can also bring you problems in the future.

PowerShell - Compare two CSVs and use SideIndicators to export the differences to separate files

I'm needing a little help creating a PowerShell script that will compare two csv files, and identify the differences specific to each file. This will be used for Active Directory user management, and will either create or disable accounts based on which csv the users are in.
I need to use the Student ID column header for the comparison since that is the only common and unique attribute shared on the accounts.
StudentRoster.csv (reference file) - I need to see a list/export of Students from this file that are not in the ActiveDirectory.csv. I will use this list to create those users in AD.
ActiveDirectory.csv - I need to see a list/export of Students in this file that are not in the StudentRoster.csv. Users on this list will be disabled in AD.
Headers/Columns:
Student ID, Last Name, First Name, Grade
I'm using the below code, but I'm not sure how to tell it to flag the user as either create/disable using the SideIndicator, and how to export to the create or disable csv.
Compare-Object -ReferenceObject $(gc C:\users\Me\desktop\Test\StudentRoster.csv) -DifferenceObject $(gc C:\users\Me\desktop\Test\ActiveDirectory.csv) | Export-Csv C:\users\Me\desktop\test\export.csv
$referenceObject = Import-Csv C:\users\Me\desktop\Test\StudentRoster.csv
$differenceObject = Import-Csv C:\users\Me\desktop\Test\ActiveDirectory.csv
$compareParams = #{
ReferenceObject = $referenceObject
DifferenceObject = $differenceObject
Property = 'Student ID'
PassThru = $true
}
$comparison = Compare-Object #compareParams | Where-Object {$psitem.SideIndicator -eq '<='}
$comparison | Export-Csv C:\users\ardavis\desktop\export.csv -NoTypeInformation
You'll want to Import-Csv to an object with properties as headers, then Compare-Object on the property "Student ID" and PassThru to get all fields.
We filter with Where-Object to choose the items existing only in the left side of the comparison, which in this case is "StudentRoster.csv".

Need help on a power shell script to filter the CSV on Columns and display the filtered data in new sheet

I am new to power shell but learning it fast. So far i have made a script which is fetching the data from URL and creating a csv on the desktop and then i remove the first row from the CSV and saving it to desktop as csv2. I want to filter the column and copy the filtered data in new sheet. I may have to declare the array values to be looked for filtering and i need help on that. So far i have made the below script:-
\This script is made to download the asset analysis servers list with their corresponding site address and country and will save the output to CSV on C:\Users\vtarwani\Desktop.
Invoke-WebRequest -Uri "Link to URL" -OutFile "C:\Users\tarwaniv\Desktop\file1.csv"
$import = get-content "C:\Users\tarwaniv\Desktop\file1.csv"
$import | select-Object -Skip 1 | Set-Content "C:\Users\tarwaniv\Desktop\file2.csv"
Import-csv -Path "C:\Users\tarwaniv\Desktop\file2.csv" -Header "#Active Servers", "Street Address" , "City", "Country" | Where-Object {$_.Country -eq "UNITED STATES"}
I agree with #Theo and #Olaf. This is difficult to follow. Hopefully you'll be able to build off an example like this:
$WebFile = "C:\Users\tarwaniv\Desktop\file1.csv"
$Out_Dir = "C:\Users\tarwaniv\Desktop\"
$Headers = "#Active Servers", "Street Address" , "City", "Country"
Invoke-WebRequest -Uri "Link to URL" -OutFile $WebFile
Import-csv -Path $WebFile -Header |
Select-Object -Skip 1 |
Group-Object -Property Country |
ForEach-Object{
$OutFile = $Out_Dir + $_.Name
$_.Group | Export-Csv -Path $OutFile -NoTypeInformation
}
Note: using -Skip parameter on Select object should skip the first record coming from Import-Csv.
Use Group-Object to group on the Country. That will output its own objects, but the name property is what you grouped on, in this case Country, and the Group property has the original objects in it. So we can use these 2 properties to name an output file then export the objects to the new Csv file.
If you want to only output a subset of the columns coming from the initial file. add the -Property parameter to the Select-Object command like:
Select-Object -Skip 1 -Property <PropertiesToSelect>
Note: You can declare an array of properties similar to $Headers above.
If you want top filter on additional columns, and assuming they were included in the Select-Object command just build on the Where-Object clause.
Please bear in mind I couldn't really test this, so consider it a starting point. That said let me know how it turns out. Thanks.

Remove #{ColumnName from Powershell results

I'm relatively new to PowerShell scripting and have mainly been cobbling together different scripts and cmdlets from Googling what I'm trying to do. One problem that I'm unable to Google, or search for on StackExchange, because of the special characters is having all my results come out as #{ColumnName=ColumnData}.
Here's an example script I found somewhere for pulling all the members of an AD group.
$Groups = Get-ADGroup -Filter {Name -like "!GroupName"}
$path = $groups
$myCol = #()
ForEach ($Group in $Groups)
{
$Members = #(Get-ADGroupMember "$Group")
ForEach ($Member in $Members){
try{
$user = get-aduser -identity $member -properties displayname
$MyObject = New-Object PSObject -Property #{
Displayname = $user.Displayname
}
$mycol += $MyObject}
catch {}}
}
Write-Host $MyCol | FL
I'm pretty sure there are better ways to get the members of an AD group but that's not the issue at the moment. The problem is all the data comes out like #{Displayname=Lawrence, Kimberly} and this happens with many of the scripts I've thrown together.
Any ideas on how to write scripts properly so I can just get DisplayName = Lawrence, Kimberly?
I agree your code is complex and it does not need to be. A couple of things that are important to mention is why your output looks the way it does.
You are creating an array of PSCustomObjects which function similar to hash-tables. In the end of your processing you have an array of objects with the property DisplayName. Since you are using Write-Host to display the the contents of $myCol it needs to cast it a string array in order to display it. You would see similar output if you just typed [string[]]$myCol. I should hope that you are doing something else in the processing as like the other answers show you have a very complicated way of getting what you are looking for.
Without beating the horse about those other solutions I will suggest some minor changes to yours as it stands. Your title and last sentence contradict what you are looking for since you want to remove the ColumnName in the title and the last sentence you are looking for output like DisplayName = Name.
Changing the last line will address both of these. If you just want the displaynames on there own
$myCols | Select-Object -ExpandProperty DisplayName
Lawrence, Kimberly
and if you actually want the other format you could do this
$myCols | ForEach-Object{
"DisplayName = $($_.DisplayName)"
}
Again, like the other answers, I stress that your code could use simple overhaul. If you needed to understand why it was working the way it way I hope I helped a little.
This actually has nothing to do with Active Directory; You are creating custom objects, then outputting them directly, and by default that is how PowerShell will format the output if you use Write-Host (which is intended to customize output). If you would like to be more specific about what your output should look like, we can help, but here is an example that outputs the results as just a list of strings, just using Write-Output:
$myCol = #()
$MyObject = New-Object PSObject -Property #{ DisplayName = "Lawrence, Kimberly" }
$myCol += $MyObject
$MyObject = New-Object PSObject -Property #{ DisplayName = "Hello, World" }
$myCol += $MyObject
# The default will show at-symbols, etc: Write-Host $MyCol | FL
Write-Output $myCol
The output will be:
DisplayName
-----------
Lawrence, Kimberly
Hello, World
Try this:
Get-ADGroup -Filter "Name -like '!GroupName'" |
Get-ADGroupMember |
Get-ADUser -Properties DisplayName |
Select-Object DisplayName
When I ran your code, I also got the hashes, even without special characters. Your code is way too unnecessarily complex.

Output custom value into PS table when value returned is $null or similar

I am generating a report out of AD of users with contract expiry dates listed.
So far I have been able to come up with this, which outputs to a CSV file with custom headings and the date shortened.
Get-QADUser -SizeLimit 0 -IncludedProperties AccountExpires,Domain,Name -DontUseDefaultIncludedProperties | Where { $_.Title -ne "Resource" } | Select #{Label="Domain";Expression={(($_.Domain).Name)}},#{Label="Employee Name";Expression={($_.Name)}},#{Label="Contract Expiry Date";Expression={(($_.AccountExpires).ToShortDateString())}},title,department,Office | Export-Csv C:\ExportForHR.csv -NoTypeInformation
What I'm wanting to do is put a custom value in column "Contract Expiry Date", if they have no value.
I.e. if I don't have a contract, the default value is null, therefore nothing shows in the spreadsheet. But what if I wanted to put "No contract expiry" or "Full time expiry" in the field instead?
Couldn't find anything that would be suitable using the command above. I could probably write a full powershell script to output to a CSV file by not using things like Select and export-csv, but I'd rather not, unless I really have to.
You're about 95% of the way there. The script block in the Expression section of Select-Object is a full script block, so you can perform the test right in there:
Get-QADUser -SizeLimit 0 -IncludedProperties AccountExpires,Domain,Name -DontUseDefaultIncludedProperties |
Where { $_.Title -ne "Resource" } |
Select-Object
#{Label="Domain";Expression={(($_.Domain).Name)}},
#{Label="Employee Name";Expression={($_.Name)}},
#{Label="Contract Expiry Date";Expression={
if ($_.AccountExpires -ne $null) {
$_.AccountExpires).ToShortDateString()
} else {
$CustomValue
}
},
title,
department,
Office
| Export-Csv C:\ExportForHR.csv -NoTypeInformation