Setting a DateTime to $null/empty using PowerShell and the SCSM cmdlets - powershell

I'm currently trying to sync additional attributes from the AD (Active Directory) for user objects in SCSM (System Center Service Manager) using a PowerShell script.
The extension I wrote for this, includes an attribute for the expiration date of a AD user account (DateTime value, named DateTimeAttribute in the example) if the user account doesn't expire it should be empty/null.
Using Import-SCSMInstance, which should be similar to a CSV import, it kind of works by passing "null" for the field. The problem is that Import-SCSMInstance seems to be quite unreliable and it doesn't offer any kind of information of why it works or doesn't work. Using Update-SCSMClassInstance seems to work a lot better but I can't figure out a way to clear the field using this and even using [DateTime]::MinValue will result in an error, stating that it's an invalid value.
So would anyone have an idea on how to clear the value using Update-SCSMClassInstance or figure out why Import-SCSMInstance might or might not work?
A simple example for this could look like the following:
$server = "<ServerName>"
$extensionGuid = "<GUID>"
Import-Module 'C:\Program Files\System Center 2012 R2\Service Manager\Powershell\System.Center.Service.Manager.psd1'
New-SCManagementGroupConnection -ComputerName $server
$extensionClass = Get-SCSMClass -Id $extensionGuid
$scsmUserObject = Get-SCSMClassInstance -Class $extensionClass -Filter 'UserName -eq "<User>"'
# Error
$scsmUserObject.DateTimeAttribute = ""
# Works but fails on Update-SCSMClassInstance
$scsmUserObject.DateTimeAttribute = $null
$scsmUserObject.DateTimeAttribute = [DateTime]::MinValue
# Works
$scsmUserObject.DateTimeAttribute = "01-01-1970"
Update-SCSMClassInstance -Instance $scsmUserObject

It seems that you can't clear a date once it's filled. When you write $null, it sets the date to 1-1-0001 01:00:00, which is an invalid date causing the update-scsmclassinstance to fail.
What we have set as a user's AD property when we don't want something to expire, is 2999-12-31 (yyyy-MM-dd). Perhaps this could help, although it's not directly what you asked for...
Also, you can use the pipeline to update a property in SCSM:
Get-SCSMClassInstance -Class $extensionClass -Filter 'UserName -eq "<User>"' | % {$_.DateTimeAttribute = <date>; $_} | update-scsmclassinstance

It doesn't look like it's currently possible to clear custom date attributes using the PowerShell cmdlets.

Related

MS Graph API - Group & membership info

I'm trying to pull out a listing of all groups in our Azure Active Directory org along with all the associated members (be them users, groups, contacts, etc).
Since I was unable to locate a method to do this through the various Microsoft portals with a simple export button I began the process of obtaining access to the Microsoft Graph API/SDK via Powershell.
I'm by no means a PowerShell expert as it's not one of my go-to scripts; however, from what I can tell the ability to pull group info in this fashion is fairly limited.
The following is what I've been able to accomplish thus far:
Pull in a list of the groups using Get-MgGroup -All
Use Get-MgGroupMembers to pull back a list of Directory Objects.
This is where I get stuck. From what I've read it looks like a Directory Object by default only returns the ID and the Deleted Date. I'd like to get a display Name for these objects; I can obviously do this by running the appropriate 'Get' cmdlet for the type of directory object (i.e. Get-MgUser); From what I can tell the type of directory object can't be gleaned via PowerShell with out 'trial-and-error'... This seems highly inefficient to simply get a displayName.
Is there a more effective way to determine either the displayName of a Directory Object via a PowerShell cmdlet or at the very least a type so I can write a case statement to run the right cmdlet on the first try?
For the record this is going to be incorporated in to a Powershell Script, the current iteration of which looks like this and sorta works okay... assuming the Id passed in $member.Id belongs to a User type directory object.
Connect-MgGraph
$groups=Get-mgGroup -All
ForEach ($group in $groups){
$members = #{}
$members = Get-MgGroupMember -GroupId $group.Id -All
ForEach ($member in $members){
$user = Get-MgUser $member.Id
Write-Output $object.ODataType
Write-output $group.DisplayName "," $member.Id "," $user.UserType"," $user.DisplayName "," $user.UserPrincipalName "," $user.Mail >> C:scripts\Azure_Groups.txt
}
}
Would appreciate any direction/assistance on this. Thanks in advance!
Not sure why its not returning all the details on the PowerShell query:
This is working fine in MS Graph Explorer with the results showing all the details of the members:
For more details:https://learn.microsoft.com/en-us/graph/api/group-list-members?view=graph-rest-1.0&tabs=http#example-1-get-the-direct-membership-in-a-group

Get AD user by providing fullName and manager full name

It might look silly but I'm struggling with finding user with Powershell by providing his full name and his manager full name. Purpose of script is to get SamAccountName and Email Address by using mentioned values which are provided by other team (these are the only unique values I get - getting user by Full Name is not any kind of problem, but it's possible that it'll return multiple results, and that's why Manager Full Name would determine appropriate result).
First I was using simple command
Get-ADUser -server $gc -Filter { (CN -eq $uFullName) -and (extensionAttribute4 -eq $mFullName) }
It worked great, but unfortunately I noticed that not all accounts use extensionAttribute4 to hold manager full name. I thought of using Filter on manager property but when I tried to use (Manager -like "*value*") it returned that like operator isn't supported by this attribute.
I'm still trying to find solution for this but maybe someone will have some solution to this situation.
Thank you in advance.

How to use Remove-LocalGroupMember to remove from a server?

I have the following script that is supposed to remove members from a server:
$ssasInstance = ""
$accountName= ""
Import-Module SqlServer
[Microsoft.AnalysisServices.Server]$SSASserver = New-Object ([Microsoft.AnalysisServices.Server])
$SSASserver.Connect($ssasInstance)
$role= $SSASserver.Roles["Administrators"]
$role.Members.Remove($accountName)
$role.Update()
The problem is for some reason Remove() is not really working, no errors generated, but it doesnt remove the user.
I tested the script by instead adding a user, $role.Members.Add($accountName) and this works great! so i know that it must be a bug with the remove() method, and the only option I have is to use Remove-LocalGroupMember
I tried just using it like this:
$ssasInstance = ""
$accountName= ""
Import-Module SqlServer
[Microsoft.AnalysisServices.Server]$SSASserver = New-Object ([Microsoft.AnalysisServices.Server])
$SSASserver.Connect($ssasInstance)
$role= $SSASserver.Roles["Administrators"]
Remove-LocalGroupMember -Group "Administrators" -Member "$accountName"
$role.Update()
but that doesnt work either...although i think its because it doesnt know exactly where its removing from...
I tried this too, but to no avail:
Remove-LocalGroupMember -Group "$role" -Member "$accountName"
So how can i integrate this module into my script?
This is an unfortunate confluence of circumstances: when you do
$role.Members.Add("member")
This works because, under water, the string "member" is implicitly converted by PowerShell to a RoleMember with a Name of member and an empty Sid. All fine. However, if you then do
$role.Members.Remove("member")
Nothing happens, because you will create a new RoleMember instance, and since RoleMember has no implementation of .Equals() (a fairly bizarre oversight), different instances will never be considered the same.
This means you can only remove members by getting the actual instance in the collection (or by index, I suppose):
$member = $role.Members.Where{$_.Name -eq "member"} | Select -First 1
$role.Members.Remove($member)
Note that you will not get an error if there is no such member (because Remove allows $null, again in a rather bizarre oversight), so you may want to check for $member -eq $null if you want to verify that.
Definitely do not use Remove-LocalGroupMember -- that cmdlet is part of a completely different module and removes members from local Windows groups, not SSAS roles.

How do I use Set-ADuser with the -Instance parameter to update an attribute to blank?

We've been using Powershell to bulk update our AD for several years with data from a CSV file. The code is pretty straight forward:
$Empinfo = Import-CSV AFile.csv
$EmpAD = Get-Aduser someone
$EmpAD.Title = $EmpInfo.Title
$EmpAD.streetAddress = $Empifo.street
$EmpAD.PostalCode = $Empifo.zip
<snip>
Set-ADUser -Instance $EmpAD
Recently, the street and zip info have been blanked for some people due to organizational weirdness. When we run the same script and try to set, say streetAdress to nothing, Set-ADuser throws a "replace" error.
(Note that I tried setting streetaddress to a single space and it still failed.)
After much trial and error, today I was able to make it work by testing for blankness and using the following:
if (Empinfo.street -eq $null) {
Set-ADUser $EmpAD -Clear streetaddress,postalCode
} else {
$EmpAD.streetAddress = $Locations[$site].street
$EmpAD.PostalCode = $Locations[$site].zip
}
In other words, we have to issue a specific -Clear action to accomplish this.
Is this how we should expect this to work? I cannot see anything in the -Instance parameter docs that says you cannot empty an attribute in the manner we were trying.
Yes , you have to use -Clear like how you have already done in the sample code in order to accomplish this. Thats the correct way to do that.
Empty field is actually holding the attribute value as Null.
So clearing that is important.

Find and replace custom attribute values in AD using Powershell

So I have an interesting script I am trying to figure out, basically I need to change a custom attribute value to a new one. The problem is its for both users and computers and not specific to the groups. So for instance the value might be Billing1 for several users in an OU and this need to be Billing2. So I need to find any instance of the Value of Billing1 and change it to Billing2 not knowing the user or computer object. I can successfully change one at a time if I know who the user is by using Set-ADUser, Set-ADComputer and even with Set-AdObject but I need to figure out a Find and replace function.
I have searched for this and I have found examples of where I can use CSV for users and computers but again I don't know who has what since the value in the attribute can vary and also changes if a reorg happens.
got the correct script...
Get-ADComputer -Properties enterattributename -Filter {enterattributename -like "value to search" } |Set-ADComputer –replace #{ enterattributename =”value to change”}
this also can be applied to Get-ADUser and Get-ADObject