I am attempting to grab a SAMAccountName from a SIP address attribute in AD. I keep getting a syntax error that I just can't figure out. I have used similar code to grab a SAMAccountName using the employeeNumber attribute. I have to wonder if the "-" in the attribute name has anything to do with the syntax error.
Import-Csv -Path .\SIP.csv | ForEach-Object {
$sipGet = Get-ADUser -Filter "msRTCSIP-PrimaryUserAddress -eq $($_.'msRTCSIP-PrimaryUserAddress')" |
select -Expand SamAccountName
$_ | select *,#{Name='SamAccountName';Expression={$sipGet}}
} | Export-Csv -Path .\SIP.csv -NoTypeInformation
Any help would be greatly appreciated!
Get-ADUser does not know -eq as a filter. Instead, use plain equal sign, and wrap the string in escaped double quotes.
$sipGet = Get-ADUser -Filter "msRTCSIP-PrimaryUserAddress = \"$($_.'msRTCSIP-PrimaryUserAddress')\"" |
select -Expand SamAccountName
Should do. (Can't test right now, have no access to AD environment)
Related
I have a computers that have assigned to users as managedby, I want to get list in JSON format where hostname is a key, and user attributes are values.
But I stuck to get that in one command :/ and put that in json, so use csv for a while.
I run these 2 commands succesfuly:
Get-ADComputer -Filter * -property managedby | select name, managedby > C:\Windows\Temp\computerowners.csv
Get-ADUser -Filter * -SearchBase 'CN=My User,DC=example,DC=com' -Properties SamAccountName | Format-Table -Property Name, samaccountname, userprincipalname -AutoSize
where search base is managedby value from first one.
I expect to have output like that:
hostname, name, samaccountname, userprincipalname
I try to combine above 2 commands like that:
Get-ADComputer -Filter * -property managedby | foreach {get-aduser -Filter * -SearchBase $managedby -Properties name, samaccountname, userprincipalname} | select name, samaccountname, userprincipalname > C:\Windows\Temp\computerowners.csv
but it want work - as not pickup managedby properly as I understand... any help with saving that in json will be more than welcome.
You didn't define the variable $managedby that you use in the ForEach-Object loop, hence the variable is $null. You need to use the property ManagedBy of the current object in the pipeline ($_.ManagedBy).
With that said, you're making the whole thing way more complicated than it needs to be. PowerShell can do a lot of the heavy lifting for you if you allow it to. Get-ADUser can read from the pipeline, so all you need to do is pass the owner's distinguished name. You also don't need to explicitly specify the properties Name, SamAccountName and UserPrincipalName, because Get-ADUser returns them by default. Plus, since you want CSV output anyway, use Export-Csv instead of the redirection operator.
Get-ADComputer -Filter * -Property managedby |
Select-Object -Expand ManagedBy |
Get-ADUser |
Select-Object Name, SamAccountName, UserPrincipalName |
Export-Csv C:\Windows\Temp\computerowners.csv -NoType
To include the computername in the output adjust the above code as follows:
Get-ADComputer -Filter * -Property managedby |
ForEach-Object {
$computer = $_.Name
if ($_.ManagedBy) { Get-ADUser $_.ManagedBy } else { '' }
} |
Select-Object #{n='ComputerName';e={$computer}}, Name, SamAccountName,
UserPrincipalName |
Export-Csv C:\Windows\Temp\computerowners.csv -NoType
To get a datastructure that can be exported to JSON using the computername as the key for the nested user attributes a different approach would be more elegant, though. Collect all relevant user attributes in a hashtable with the computername as the key:
$computers = #{}
Get-ADComputer -Filter * -Property managedby | ForEach-Object {
$computers[$_.Name] = if ($_.ManagedBy) {
Get-ADUser $_.ManagedBy | Select-Object Name, SamAccountName, UserPrincipalName
} else {
New-Object -Type PSObject -Property #{
Name = ''
SamAccountName = ''
UserPrincipalName = ''
}
}
}
Then create an object from that hashtable and convert it to JSON:
New-Object -Type PSObject -Property $computers | ConvertTo-Json
This should get you pretty far:
Get-ADComputer -Filter * -Property ManagedBy,CN | ForEach-Object {
# only query AD if there actually is a manager
if ($_.ManagedBy) {
$manager = $_.ManagedBy | Get-ADUser
} else {
$manager = $null
}
# return a custom object with 4 properties
[pscustomobject]#{
hostname = $_.CN
name = $manager.Name
samaccountname = $manager.SamAccountName
userprincipalname = $manager.UserPrincipalName
}
}
Note: Any value created in a script block and not explicitly captured in a variable or explicitly discarded via Out-Null automatically becomes a return value of that block. In this case, the ForEach-Object body will emit a series of PSCustomObject instances.
Use the result in any way you like, for example format it as JSON or CSV.
Related reading
How do I return a custom object in Powershell that's formatted as a table?
Jonathan Medd's Blog: PowerShell v3 – Creating Objects With [pscustomobject]
I have a CSV file with a list of PC's in my domain. I wanted to get the "Description" Field information from AD for each of the machines listed in AD. This is what I have so far:
Import-Module ActiveDirectory
Get-ADComputer -Filter {OperatingSystem -NotLike "*Server*"} -SearchBase "OU=Active,OU=Regular Computers,OU=EPComputers,DC=epenergy,DC=net" -Properties * | Select-Object Name,OperatingSystem,CanonicalName | Export-Csv C:\PCList.csv -NoTypeInformation
I am not sure where I need to add in the get-ADObject and filter out the Description Field or even where to begin on that. Any help would be awesome!
Thank You!
You are currently only outputting the following properties: Name,OperatingSystem,CanonicalName to your CVS. If you add Description to the list of objects your are selecting you should also get the Description properties too.
Select-Object Name,OperatingSystem,CanonicalName,Description
this would make your block of code:
Import-Module ActiveDirectory
Get-ADComputer -Filter {OperatingSystem -NotLike "*Server*"} -SearchBase "OU=Active,OU=Regular Computers,OU=EPComputers,DC=epenergy,DC=net" -Properties * | Select-Object Name,OperatingSystem,CanonicalName,Description | Export-Csv C:\PCList.csv -NoTypeInformation
I did my testing using the following though, it returned the name, Description, OperatingSystem and CanonicalName of all of the machines on my domain:
Import-Module ActiveDirectory
Get-ADComputer -Filter * -Properties * | Select-object name,Description,OperatingSystem,CanonicalName | Export-Csv C:\PCList.csv -NoTypeInformation
You might find this website useful, I can almost always find answers to my powershell questions on ss64
Good day!
I am trying to get the opened applications that you can see on the taskbar, the computers' IP address and its username. After which, I would save it in a text file with the values separated by commas. Now, I want everything to be saved in the text file but in my set of codes, the results from Get-process are the only ones that are saved on the text file. How can I include the IP address and the username saved together with the results from Get-process on the same text file.
Here is my code:
$savepath = "C:\Users\$([Environment]::UserName)\Desktop\apps\runningapps.txt"
Get-process | where {$_.mainwindowtitle.length -ne 0} | select name, mainwindowtitle| Export-Csv $savepath -notype
Get-WMIObject -class Win32_ComputerSystem | select username| Export-Csv $savepath -append -notype
Get-WmiObject Win32_NetworkAdapterConfiguration |
Where { $_.IPAddress } | # filter the objects where an address actually exists
Select -Expand IPAddress | # retrieve only the property *value*
Where { $_ -notlike "*:*" }|Export-Csv $savepath -append -notype
I think your issue is because the three objects you are exporting have different attributes, you are having the trouble?
If you really want to put it all on one file, then you could
ConvertTo-Csv -notype | Add-Content $savepath
I am trying to take a filename such as: John_Doe_E_DOB_1/1/46_M(This is the gender)_ID_0000000_IMG_FileName_Date-of-File_1/1/15_Doc-page-1 And create a CSV file to open in Excel with column headers for: Last Name, First Name, MI, ID No, File Name, Date of File along with doc type. Here's my code so far:
Get-ChildItem -Path C:\Users\name\desktop\test -Recurse | ForEach-Object {$_ | add-member -name "Owner" -membertype noteproperty -value (get-acl $_.fullname).owner -passthru} | Sort-Object fullname | Select BaseName,Name,Owner | Export-Csv -Force -NoTypeInformation C:\Users\name\desktop\test\thing.csv
All this is doing is dropping that really long file name in at the top, and then adding the ext at the end in another column. Example:
John_Doe_E_DOB_1/1/46_M(This is the gender)_ID_0000000_IMG_FileName_Date-of-File_1/1/15_Doc-page-1 Would be in column 1 and
John_Doe_E_DOB_1/1/46_M(This is the gender)_ID_0000000_IMG_FileName_Date-of-File_1/1/15_Doc-page-1.txt <----- Would be the only difference in column 2
How can I split this up for over a million files, all different lengths, and sizes, and get it to break up into the categories listed above? All help would be greatly appreciated.
I would replace the Select stage of your pipeline with a call to a filter function like this:
filter GenObj {
$parts = $_.FullName.Split('_')
new-object pscustomobject -property #{
Owner = (get-acl $_.fullname).owner
FirstName = $parts[0]
LastName = $parts[1]
MiddleInitial = $parts[2]
# Fill in the rest
}
}
Get-ChildItem -Path C:\Users\name\desktop\test -Recurse |
Sort-Object fullname |
GenObj |
Export-Csv -Force -NoTypeInformation C:\Users\name\desktop\test\thing.csv
This will create a new custom object with all the properties on it that correspond to the parts of the filename you want to extract.
This string splitting approach may not work depending on how you handle names with no middle initial.
Also be aware that if you are processing a million files, the use of Sort-Object will cause every single FileInfo object (one for every file) to get buffered in memory so the sort can be performed. You may likely run out of memory and the command will fail. I would consider removing Sort-Object in this scenario.
Trying to create a function that takes objects on the pipeline using the alias property. I'm not sure where this is going wrong.
Example of the process:
function Get-Name
{
Param
(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias("givenname")]
[System.String] $FirstName,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias("sn")]
[System.String] $LastName
)
write-host "firstName = $FirstName / $($FirstName.GetType().FullName)"
Write-host "LastName = $LastName / $($LastName.GetType().FullName)"
}
If I run this command:
Get-Aduser -filter {sn -eq 'smith'} -properties sn,givenname | Get-Name
the output looks like this:
firstName = / string
LastName = / string
The Function never seems to grab the sn and givenname attributes from the passed in object. What am I missing?
The AD Cmdlets are to blame here
The problem here is that the AD Cmdlets return objects in really non-standard ways. For instance, with any other cmdlet if you take the output of the command and select a non-existing property, you'll get back nothing, like this:
get-date | select Hamster
Hamster
-------
>
See, nothing. Sure, it says Hamster, but there is no actual Object there. This is standard PowerShell behavior.
Now, look at what Get-ADUser does instead:
get-aduser -Filter {sn -eq 'adkison'} | select Hamster
Hamster
-------
{}
It creates a $null! So what will happen with your function is that PowerShell will look for a property of -LastName or -FirstName, get a $null and then stop right there. It sucks!
The best way around this is to swap the parameter names like this, and it will still work:
function Get-Name
{
Param
(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias('FirstName')]
[System.String] $givenname,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias("sn","lastname")]
[System.String] $Surname
)
write-host "firstName = $givenname / $($givenname.GetType().FullName)"
Write-host "LastName = $SurName / $($SurName.GetType().FullName)"
}
get-aduser -Filter {sn -eq 'adkison'} | Get-Name
firstName = James / System.String
LastName = Adkison / System.String
Want to know more?
Check out this awesome answer from /u/JBSmith on the topic.
From what I've been able to determine, it isn't technically the AD cmdlets that are to blame, but the types in the Microsoft.ActiveDirectory.Management namespace--in this case, ADUser. The properties on ADUser are ultimately all just stored in a private SortedDictionary and fetched through get accessors, which might explain why it doesn't work quite as expected.
As alluded to by Colyn1337 in a previous comment, ADUser doesn't contain a property (or key) named either sn or LastName by default, so you'd need to either include an alias of Surname on your LastName parameter or select sn in your Get-ADUser call:
Get-ADUser -Filter {sn -eq 'Adkison'} -Properties sn | Get-Name
That still won't work, but from there you can just pipe to Select-Object before piping to your function:
Get-ADUser -Filter {sn -eq 'Adkison'} -Properties sn | Select * | Get-Name
Of course, you could also just select the specific properties you need instead of * in Select-Object. I assume this works because it resolves the ADUser dictionary into a PSCustomObject with concrete properties. Once resolved, they will match aliases as well as the actual parameter names.