PowerShell: Search all property values - powershell

How can I search all the properties of a single object for a given string?
Say I have the following command output:
get-aduser jtest -properties *
DistinguishedName : CN=jtest,CN=Users,DC=confederationc,DC=on,DC=ca
Enabled : True
GivenName : Justus
Name : jtest
ObjectClass : user
ObjectGUID : f4d31d45-0505-433e-9442-152419e75d26
SamAccountName : jtest
SID : S-1-5-21-2138664166-620177494-281947949-184391
Surname : Test
UserPrincipalName : jtest#confederationcollege.ca
...output truncated
How can I search for any property that contains the string "jtest"?
I feel like I must be missing something obvious.

There's always findstr (case insensitive), but the result is only text. This is a common question.
get-aduser jtest | findstr /i jtest
Name : jtest
SamAccountName : jtest
UserPrincipalName : jtest#confederationcollege.ca
This doesn't work in all cases, but it does for registry entries. This can match against most property names or values. It depends on what "$_" converts to as a string. Generic pscustomobjects work. It won't work for the get-aduser example (the object converts to a distinguishedname string).
get-itemproperty hkcu:\key1 | ? { $_ -match 'foo' } # or 'emspace'
value1 : 17
emspace : foo bar
refcount : {255, 255}
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\key1
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER
PSChildName : key1
PSDrive : HKCU
PSProvider : Microsoft.PowerShell.Core\Registry
get-itemproperty hkcu:\key1 | % { "$_" } # showing string conversion
#{value1=17; emspace=foo bar; refcount=System.Byte[]; PSPath=Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\key1; PSParentPath=Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER; PSChildName=key1; PSDrive=HKCU; PSProvider=Microsoft.PowerShell.Core\Registry}

You can use the hidden psobject memberset on any object in PowerShell to access its underlying properties programmatically:
foreach($user in Get-ADUser jtest){
foreach($property in $user.psobject.Properties){
if($_.Value -like '*jtest*'){
"Property '$($_.Name)' has value '$($_.Value)'"
}
}
}

Related

Get Distribution List muliple Owners in exchange

i need a power shell cmd or script which will give me the list of all the Distributions list along with the OWNERS of that like managed by.
But , if there are multiple users inside managedby attribute then I am getting System.Object[].
My question are :
1- how can we get multiple users for managedby attribute ?
2- how can we add employeeid and samaccountname for managedby users ?
3 - if there is no managed by user then it display "NO MANAGED BY USER"
4- I want to get mail groups not hidden.
script :
$DGroups=Get-DistributionGroup -resultsize unlimited
$mastertable=#()
ForEach($Group in $DGroups){
$table=[pscustomobject][ordered]#{
Name = $group.name
"Managed By" = $group.managedby.name
"DistinguishedName" = $group.DistinguishedName
}
$Mastertable += $table
}
$Mastertable | export-csv C:\tmp\managedby.csv -NoTypeInformation
My output :
"Name","Managed By","DistinguishedName"
"IT research","System.Object[]","CN=IT research,OU=TEST,DC=contoso,DC=com"
"Test Mail Group 1","User01","CN=\Test Mail Group 1,OU=Test,OU=COMPANY,DC=contoso,DC=com"
"Test Mail Group 2",,"CN=\Test Mail Group 2,OU=Test,OU=COMPANY,DC=contoso,DC=com"
My desired output :
"Name","Managed By","DistinguishedName","OWNERSAMACCOUNTNAME","OWNEREMPLOYEEID"
"IT research","User01;User02","CN=IT research,OU=TEST,DC=contoso,DC=com","tst124;tst125","242333;344232"
"Test Mail Group 1","User01","CN=\Test Mail Group 1,OU=Test,OU=COMPANY,DC=contoso,DC=com","tst124","242333"
"Test Mail Group 2","NO MANAGED BY USER","CN=\Test Mail Group 2,OU=Test,OU=COMPANY,DC=contoso,DC=com"
LAST UPDATE :
[PS] C:\Windows\system32>$group.ManagedBy
OrgHierarchyToIgnore :
IsDeleted : False
Rdn : CN=John T
Parent : contoso.com/COMPANY/IT
Depth : 5
DistinguishedName : CN=John T,OU=IT,DC=contoso,DC=com
IsRelativeDn : False
DomainId : contoso.com
PartitionGuid : 59ce2f71-eaa2-4ddf-a4fa-f25069d0b324
PartitionFQDN : contoso.com
ObjectGuid : 62d578e8-b69c-45bc-967a-e530d72792e1
Name : John T
[PS] C:\Windows\system32>$group.ManagedBy | ForEach-Object { $_ | Get-ADUser -Properties EmployeeId }
Get-ADUser : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties
do not match any of the parameters that take pipeline input.
At line:1 char:42
+ $group.ManagedBy | ForEach-Object { $_ | Get-ADUser -Properties EmployeeId }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (contoso.com/COMPANY/IT/John T:PSObject) [Get-ADUser], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,Microsoft.ActiveDirectory.Management.Commands.GetADUser
It is my understanding the ManagedBy attribute stores the DistinguishedName(s) of one or more users (or none at all).
I haven't tested this myself, but you could try:
$DGroups = Get-DistributionGroup -ResultSize Unlimited
$mastertable = foreach($group in $DGroups) {
# initialize a PsCustomObject
$data = [PsCustomObject]#{
Name = $group.Name
DistinguishedName = $group.DistinguishedName
ManagedBy = 'NOT MANAGED'
OwnerSamAccountName = $null
OwnerEmployeeId = $null
}
if ($group.ManagedBy) {
$managedBy = $group.ManagedBy | ForEach-Object { Get-ADUser -Identity $_.DistinguishedName -Properties EmployeeId }
$data.ManagedBy = $managedBy.Name -join ';'
$data.OwnerSamAccountName = $managedBy.SamAccountName -join ';'
$data.OwnerEmployeeId = $managedBy.EmployeeId -join ';'
}
# output this data to be collected in $mastertable
$data
}
$mastertable | Export-Csv 'C:\tmp\managedby.csv' -NoTypeInformation

How to receive OU values separately in different columns via powershell?

The powershell query I use to get the list of all the workstations registered in AD is on below:
Get-ADComputer -Filter {OperatingSystem -NotLike "*server*"} -Property * | Select-Object Name,SID,DistinguishedName,whenCreated,LastLogonDate | Export-CSV allworkstations2.csv -NoTypeInformation -Encoding UTF8
An example of "DistinguishedName" is like:
CN=500-AV,OU=Workstations,OU=SecondOU,OU=ThirdOU,OU=FourthOU,DC=myDC1,DC=myDC2
CN=600-AV,OU=FirstOU,OU=SecondOU,OU=ThirdOU,OU=FourthOU,OU=FifthOU,DC=myDC1,DC=myDC2
Please note that the number of OU values for each workstation can differ, can't say it is always 4. Edit: Maximum number of OU a workstation can have is 5.
I need all the OU values separately, as different columns (OU1, OU2, ... etc). In Excel, I was using this formula below to receive all the OU values in separate columns:
=TRIM(MID(SUBSTITUTE(MID($B2,FIND(",OU=",$B2)+4,FIND(",DC=",$B2)-FIND(",OU=",$B2)-4),",OU=",REPT(" ",999)),(COLUMN(A:A)-1)*999+1,999))
What I want is to get the OU values in different columns directly from the powershell. I couldn't find out the correct syntax to update my query accordingly. Any help would be appreciated.
Here is the version info:
Edit2: Example of expected output:
WorkstationName SID OU1 OU2 OU3 OU4 OU5 createdDate LastLogin
500-AV X Workstations SecondOU ThirdOU FourthOU null 1/1/2018 6/1/2018
600-AV X FirstOU SecondOU ThirdOU FourthOU FifthOU 1/1/2018 6/1/2018
now that you clarified things a tad, i think this does what you want. [grin]
what it does ...
creates two user objects to work with
delete this when you are ready to work with your data set. [grin]
iterates thru the user list
splits the DistinguishedName to get the OUs
makes the $OuList variable into an array even if there is only one OU
builds a custom object with the anticipated max number of OUs
you will need to determine that ahead of time.
sends that object out to the $Results collection
displays that collection
at that point, you have a collection that will gracefully export to a CSV file. [grin]
here's the code ...
$UserList = #(
[PSCustomObject]#{
ComputerName = '111-AV'
SID = '1-22-333'
DistinguishedName = 'CN=111-AV,OU=SolitaryOU,DC=myDC1,DC=myDC2'
DateCreated = '2011-11-11'
LastLogon = '2019-08-11'
}
[PSCustomObject]#{
ComputerName = '500-AV'
SID = '1234-5678-90'
DistinguishedName = 'CN=500-AV,OU=Workstations,OU=SecondOU,OU=ThirdOU,OU=FourthOU,DC=myDC1,DC=myDC2'
DateCreated = '2001-01-01'
LastLogon = '2019-08-08'
}
[PSCustomObject]#{
ComputerName = '666-AV'
SID = '777-888-999'
DistinguishedName = 'CN=666-AV,OU=Servers,OU=SrvOu2,OU=SrvOu3,OU=SrvOu4,OU=SrvOu5,DC=myDC1,DC=myDC2'
DateCreated = '1999-12-31'
LastLogon = '2019-08-20'
}
)
$Results = foreach ($UL_Item in $UserList)
{
[array]$OuList = #($UL_Item.DistinguishedName.Split(',')).
Where({$_ -match 'OU='}).
ForEach({$_.Split('=')[-1]}).
Trim()
[PSCustomObject]#{
ComputerName = $UL_Item.ComputerName
SID = $UL_Item.SID
OU_1 = $OuList[0]
OU_2 = $OuList[1]
OU_3 = $OuList[2]
OU_4 = $OuList[3]
OU_5 = $OuList[4]
DateCreated = $UL_Item.DateCreated
LastLogon = $UL_Item.LastLogon
}
}
$Results
output to screen ...
ComputerName : 111-AV
SID : 1-22-333
OU_1 : SolitaryOU
OU_2 :
OU_3 :
OU_4 :
OU_5 :
DateCreated : 2011-11-11
LastLogon : 2019-08-11
ComputerName : 500-AV
SID : 1234-5678-90
OU_1 : Workstations
OU_2 : SecondOU
OU_3 : ThirdOU
OU_4 : FourthOU
OU_5 :
DateCreated : 2001-01-01
LastLogon : 2019-08-08
ComputerName : 666-AV
SID : 777-888-999
OU_1 : Servers
OU_2 : SrvOu2
OU_3 : SrvOu3
OU_4 : SrvOu4
OU_5 : SrvOu5
DateCreated : 1999-12-31
LastLogon : 2019-08-20

Search and delete registry values containing string using Powershell

I'm trying to find all the values recursively that contains this sub-string in it name : "~fr-FR~".
$registry = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackageDetect\" -Recurse
Foreach($a in $registry) {
($a | Get-ItemProperty).Psobject.Properties |
Where-Object { $_.Name -like '*~fr-FR~*' }
}
At this point I can retrieve all the values filtered recursively. Pasted below is example of one of the results:
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : 3
TypeNameOfValue : System.Int32
Name : Microsoft-Windows-GroupPolicy-ClientTools-Package~31bf3856ad364e35~amd64~fr-FR~10.0.17134.1
IsInstance : True
How do I remove the sub-string?

How to get object type/identifier?

In PowerShell, when I work with Active Directory specifically, often I'll compile an object containing a list of groups of people usually with $x = get-adgroup -filter {name -like "*"} | select-object name which gives me a list with a header or object type name:
name
----------
name1
name2
name3
How can I access the name header of the object or even change it to something else?
Can it be done similarly to the way I would access the string of the first entry like $x[0].name?
Further, is there a more generic way to access the string associated with an arbitrary entry?
I'm being asked to a lot of "programming" in PowerShell related to AD so any resources you can provide to help me would be greatly appreciated.
If you want to change the name you can create an expression for it in your select block:
get-adgroup -filter {name -like "*"} | select-object #{Name="WhatYouWannaCallIt";Expression={$_.Name}}
This would now give you:
WhatYouWannaCallIt
------------------
name1
name2
name3
The two things that I think you are asking for is a programmatic way to determine the name of a given property in an object.
(get-aduser $user | select name).psobject.properties
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : Matt
TypeNameOfValue : System.String
Name : name
IsInstance : True
The Name property of .psobject.properties contains most of this information and I think you might be looking for.
Was going to answer the second part with what Arco444 just said about using select-object
Do you mean:
$x = get-adgroup -filter {name -like "*"}
$x.name
or
(get-adgroup -filter {name -like "*"}).name

Powershell - How do I get expanded properties and normal in one round?

I've got a fileserver, where the files are saved in a crypted name. Now I'd like to do something like that:
Get-Item ABB667687BB581070240D48958F3BB0696921F09 | fl *
PSChildName : ABB667687BB581070240D48958F3BB0696921F09
PSIsContainer : False
VersionInfo : File: \\XYZ\ABB667687B581070240D48958F3BB0696921F09
InternalName: Setup.exe
OriginalFilename: Setup.exe
FileVersion: 5,2,0,2946
FileDescription: Evernote Installation Package
Product: Evernote®
ProductVersion: 5,2,0,2946
...continuing
BaseName : ABB667687BB581070240D48958F3BB0696921F09
Mode : -a---
Name : ABB667687BB581070240D48958F3BB0696921F09
Length : 83157856
...continuing
LastAccessTime : 05.03.2014 08:23:58
When I try with following
get-Item ABB667687BB581070240D48958F3BB0696921F09 | Select-Object -Expand VersionInfo | fl *
CompanyName : Evernote Corp., 305 Walnut Street, Redwood City, CA 94063
FileVersion : 5,2,0,2946
ProductVersion : 5,2,0,2946
ProductName : Evernote®
Now I would like to combine PSCHild, Product, Product Version, Fileversion, LastAccessTime. How can I do that?
Tried it with something like:
Get-Item ABB667687BB581070240D48958F3BB0696921F09 | ft -property #{n="Filename" ; e={$_.pschildname}}, #{n="Fileinformation";e={get-Item ABB667687BB581070240D48958F3BB0696921F09 | Select-Object -Expand VersionInfo | ft product}}
Firstly, You could absolutely use a solution similar to Kayasax's.
Personally, I find calculated properties very helpful. Other solutions such as Add-Member also work. This is a decent reference on the different options.
With that being said, here is a snippet of code covering a little of what you want (tweak as needed):
#Show Fullname, Name, and a few nested VersionInfo props for an object.
Get-Item 'C:\Program Files\Internet Explorer\iexplore.exe' |
Select-Object -Property FullName,
Name,
#{ label = "CompanyName"; expression = {$_.VersionInfo.CompanyName} },
#{ label = "FileVersion"; expression = {$_.VersionInfo.FileVersion} },
#{ label = "ProductVersion"; expression = {$_.VersionInfo.ProductVersion} },
#{ label = "ProductName"; expression = {$_.VersionInfo.ProductName} }
<# Output
FullName : C:\Program Files\Internet Explorer\iexplore.exe
Name : iexplore.exe
CompanyName : Microsoft Corporation
FileVersion : 11.00.9600.16384 (winblue_rtm.130821-1623)
ProductVersion : 11.00.9600.16384
ProductName : Internet Explorer
#>
Lastly, as a word of warning, you should rarely if ever use Format-Table (ft). This generates unusable text for your viewing only. You might see it in verbose output, but if you ever plan to use the data again, you should not be using Format-Table. Google around for many discussions on the topic : )
Cheers!
powershell allows to expand only one property at a time.
you cant do what you want in one "round".
What you can do is create a new psobject like that :
$file=ls c:\temp\putty.exe
$inf=$file |select -expand versioninfo
$myobj="dummy" | select child,product,version,write
$myobj.product=$inf.ProductName
$myobj.version=$inf.ProductVersion
$myobj.child=$file.PSChildName
$myobj.write=$file.LastWriteTime
You can use Tee-Object, along with calculated properties. Suppose you want to get those values from PowerShell.exe. Then, do it this way:
gi $PSHOME\powershell.exe |
tee -var pow |
select name,
#{n='Product';e={$pow.versioninfo.productname}},
#{n='Product Version';e={$pow.versioninfo.productversion}},
#{n='FileVersion';e={$pow.versioninfo.fileversion}},
lastaccesstime |
fl