question

PowerShellelagh avatar image
0 Votes"
PowerShellelagh asked PowerShellelagh commented

Combining Commands foreach

I want to take a couple commands and bring them together, but am unsure of how to do this.



  • I want to grab all the groups in a specific OU - This works to grab all the groups in the specified OU

$Grouplist = Get-ADGroup -Filter * -SearchBase "OU=*ou name*, OU=*ou name*, OU=*ou-name*, DC=*domain*, DC=local | Sort-Object | Select Name


  • Then I want to search through those groups and grab all the members in those group and grab their lastlogontimestamp and list any outside of the last 90 days - This works when I use a specific group name

Get-ADGroupMember **$GROUPLIST VARIABLE?** -Recursive | Get-ADObject -Properties Name, DisplayName, samAccountName, LastLogonTimestamp | Select-Object Name, DisplayName, samAccountName, @{ n = "LastLogonTimeDate"; e = { [System.DateTime]::FromFileTime($_.LastLogonTimeStamp) } }


  • I know I need to use a ForEach for this, but I don't know how - I believe this is where I should go?

ForEach ($Group in $Grouplist) ??


I know I am missing some key elements, but I am having a hard time finding what I am missing and even if I did, I am not sure I can bring it all together. The end result I am looking for is a loop that goes through each group it finds in the specified OU, grabs all the members of those groups along with their last logon and then filters to show only the users whose last logon is 90 days or greater.

I found a function somebody wrote going, I believe, in the same direction I am

function Get_LogonTimes { [CmdletBinding()] param ( [parameter(Position=0, Mandatory=$true)] $Groups ) $table = @() foreach($group in $Groups) { $users = (Get-ADGroup -Identity $group | Get-ADGroupMember |Where-Object {$_.objectClass -eq "user"}).SamAccountName foreach($user in $users) { $acct = Get-ADUser -Identity $user -Properties * $table += New-Object -TypeName psobject -Property @{ Name = $acct.Name UserName = $acct.SamAccountName LastLogon = $acct.LastLogonDate Group = $group } } } $logontimes = $table | Select Name,UserName,LastLogon,Group return $logontimes }


Like so many, I am still in the learning stages of PowerShell. Any help is appreciated, thank you!

windows-server-powershell
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

RichMatheisen-8856 avatar image
0 Votes"
RichMatheisen-8856 answered PowerShellelagh commented

See if this works for you. Note: I haven't run this code!

 $cutofflimit = New-TimeSpan -days 90
 $Grouplist = Get-ADGroup -Filter * -SearchBase "OU=*ou name*, OU=*ou name*, OU=*ou-name*, DC=*domain*, DC=local" | 
     Sort-Object -property Name |
         Get-ADGroupMember |
             ForEach-Object{
                 $o = Get-ADObject -Identity $_.distinguishedName -Properties Name, DisplayName, samAccountName, LastLogonTimestamp
                 if (((get-date) - ([System.DateTime]::FromFileTime($o.LastLogonTimeStamp))) -gt $cutofflimit){
                     $o | Select-Object Name, DisplayName, samAccountName, @{ n = "LastLogonTimeDate"; e = { [System.DateTime]::FromFileTime($_.LastLogonTimeStamp) } }
                 }
             }

Also note that if you have more than one domain controller this will not work reliably. The LastLogonTimestamp is not a replicated property. You'll have to check each DC to see which one has the most recent value and then use that to see if the user logged on within the 90 day period.

· 7
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for the assistance, it's very much appreciated!


I edited the CN accordingly, and then had to add a } on the end. Once I did that, I ran it and this is what I got back:

Get-Date : Cannot bind parameter 'Date'. Cannot convert value "-" to type "System.DateTime". Error: "String was not recognized as a valid DateTime." At line:7 char:32 + if ((get-date - ([System.DateTime]::FromFileTime($o. ... + ~ + CategoryInfo : InvalidArgument: (:) [Get-Date], ParameterBindingException + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

Should get-date have anything after it? if ((get-date -? ([System.DateTime]

I tried some of the get-date parameters after it and while I got different errors, it still did not run successfully.

I will keep poking at it, but let me know if you have any ideas.

0 Votes 0 ·

The "Get-Date" needed to be surrounded by parentheses. I corrected that in the code sample. I also added the missing "}".

0 Votes 0 ·

Thanks for the updates.

It's now prompting for input.

cmdlet Get-ADObject at command pipeline position 1

Supply values for the following parameters:
(Type !? for Help.)
Filter:

Why does it seem to be dismissing the -Filter *? I will continue to work on it.

0 Votes 0 ·
Show more comments