I figured this might be an easy answer, but for the life of me I can't suss out why this simple thing seems to be beating me. I am looking to output the results of
Get-Mailbox –Server MYserverName | Get-MailboxPermission | FL
piped into individual text files for each individual mailbox, with the text file named for the mailbox - e.g. I want to have a folder with the content:
C:\Example\MailboxUser1.txt
C:\Example\MailboxUser2.txt
C:\Example\MailboxUser3.txt
with each containing the mailbox permission results.
I know I can do a foreach loop along the lines of:
ForEach-Object {Out-file $_.name}
to generate the output files, but I'm not too sure how I would do this in a single step to get the permissions for all my mailboxes into individual files (I know this will give me a lot of text files!)?
Something along the lines of:
$directory = "C:\example\"
$count = 0
Get-Mailbox –Server "MYserverName" | Foreach-Object {
Get-MailboxPermission | Format-List |
Out-File (Join-Path $directory "MailboxUser-$(++$count).txt")
}
At each pass of the ForEach-Object loop (mailbox), a file will be generated with the output of the Get-MailboxPermission command.
++$count increments the value just before using it (as opposed to $count++)
If you prefer to user the Name property of the mailbox object to name the files:
$directory = "C:\example\"
Get-Mailbox –Server "MYserverName" | Foreach-Object {
$mailboxName = $_.Name
Get-MailboxPermission | Format-List |
Out-File (Join-Path $directory "MailboxUser-$mailboxName.txt")
}
Get-Mailbox –Server MYserverName | Get-MailboxPermission | foreach {out-file "$($_.name).txt"}
This would be able to get you all the permissions you need IF "name" was the property you were looking at. I don't work with exchange cmdlets so I don't know if that will count.
Related
I'm trying to get all the user photos from my office365 server. I need them to show in the Alias format which is firstname.lastname
get-mailbox | % {Get-UserPhoto $_.alias} | % {Set-Content -path "c:\export\$($_.alias).jpg" -value $_.picturedata -Encoding byte}
This works, but gives me First Name Last Name
Someone told me I need to pass mailbox parameters through the pipeline, to do what I want to do.
get-mailbox -PipelineVariable Mailbox | % {Get-UserPhoto $Mailbox.alias} | % {Set-Content -path "c:\export\$($Mailbox.alias).jpg" -value $_.picturedata -Encoding byte}
This is my new code, but it's not spitting out photos into directory. Does anyone know why this isn't working?
Cannot check this now, but I think this may work:
Get-Mailbox | ForEach-Object {
$photo = Get-UserPhoto -Identity $_.alias
Set-Content -Path "c:\export\$($_.alias).jpg" -value $photo.picturedata -Encoding byte
}
Get-ChildItem -Path E:\Server_Data\data\2015 -Recurse –File -include "*.txt","*.csv" | Where-Object {$_.Name -like "*transaction*"} | Select-Object -ExpandProperty FullName,LastWriteTime
I'm trying to list all files in a folder using Get-ChildItem and Select-Object property. When I try to use FullName variable to list the fully qualified file name, the file name is getting truncated. Tried to use -ExpandProperty to get fully qualified file name. It works for one field but if I try to list both FullName and LastWriteTime, it's not working.
The output from the power shell command will be used in MS SQL Server to load the file names into a specific table.
Please suggest proper syntax for my purpose. Appreciate your help!
Depending on your use case and input, one way to accomplish this is by having two Select-Object cmdlets in your pipeline, one to define an array of properties, and one to expand them:
PS C:\> $Name,$DisplayName,$Status = Get-Service
| Select-Object -First 1 -Property #{
Name = "MyProperties"
Expression = { $_.Name,$_.DisplayName,$_.DisplayName }
} | Select-Object -ExpandProperty MyProperties
Get-ChildItem -Path E:\Server_Data\main.sweetbeam.net\data\2015 -Recurse –File -include "*.txt","*.csv" | Where-Object {$_.Name -like "*transaction*"} | Select-Object #{Name="test";Expression={$_.FullName + "`t" + $_.LastWriteTime}} | Select-Object -ExpandProperty test
Merged the two fields and used the derived field for my purpose.
If you are only going to do this to display on the console, then you can look at using Format-Table with the -Wrap parameter to display all of the text on the console without truncating the output.
Get-ChildItem -Path E:\Server_Data\data\2015 -Recurse –File -include "*.txt","*.csv" |Where-Object {
$_.Name -like "*transaction*"
} | Format-Table FullName,LastWriteTime -Wrap
If you are planning on doing anything else with our output, then you will need to avoid the use of Format-* cmdlets as they add custom formatting to the object and render it effectively useless in the pipeline.
If you're using the output in another program, you should be converting to CSV, JSON, or XML rather than copying the formatted output. It may also be possible to insert directly into SQL using PowerShell commands.
Get-ChildItem -Path E:\Server_Data\data\2015 -Recurse –File -include "*.txt","*.csv" |
Where-Object {$_.Name -like "*transaction*"} |
Select-Object FullName,LastWriteTime |
ConvertTo-Csv -NoTypeInformation
Other options for the last command are:
JSON with ConvertTo-Json
XML with ConvertTo-xml -As String -NoTypeInformation
Late answer, but this has existed since PowerShell 3.0, so should have been an option.
get-eventlog Security `
-EntryType SuccessAudit `
-Newest 50 `
-InstanceId 4624,4634 `
-ComputerName $env:COMPUTERNAME |
Select-Object -Property *
OR (not all fields)
get-eventlog Security `
-EntryType SuccessAudit `
-Newest 50 `
-InstanceId 4624,4634 `
-ComputerName $env:COMPUTERNAME |
Select-Object -Property TimeGenerated,EventID,Message -PipelineVariable myEvent |
Foreach-Object -Process {
convertTo-Json -InputObject #{
TimeGenerated = (Get-Date $myEvent.TimeGenerated)
EventID = $myEvent.EventID
Message = $myEvent.Message.Substring(0, $myEvent.Message.IndexOf("`r"))
} -Depth 1
}
Hope I'm not late for the game. This one example works for me (Get-Service, more than 1 properties having embedded 'collections' of data)
Get-Service |
Select-Object
Name,
Status,
...
and then in the next lines in your script, the next object(s) that you want expanded should be like this
#{Name="CustomCol01";Expression={$_.ServicesDependedOn} },
#{Name="CustomCol02";Expression={$_.DependentService} }
In the example, the 2 offending objects that I need expanded are ServicesDependedOn and DependentService
So yeah by custom making new columns it expands whatever Objects for you
Tested works even when redirecting the final output to a csv like this
... > myfile.csv
I am currently working with a CSV file that has a manager's employee number, but not their SAMAccountName. I want to utilize Get-ADUser to grab the manager's SAMAccountName from their EmployeeNumber attribute and place that inside a new column in the same CSV file.
CSV sample:
"Full Name","Username","Manager","Manager User Sys ID"
"User 1","u1","1, Manager","123456"
"User 2","u2","2, Manager","234567"
"User 3","u3","3, Manager","345678"
I would like:
"Full Name","Username","Manager","Manager User Sys ID","Manager SamAccountName"
"User 1","u1","1, Manager","123456","m1"
"User 2","u2","2, Manager","234567","m2"
"User 3","u3","3, Manager","345678","m3"
I have spent some time putting together the following code. I can get a new column added and can further grab the SAMAccountName, but it only exports a single line in the new CSV file like this:
"SAMAccountName","managerUsername"
"m1","#{SAMAccountName=m1}"
Here is the code:
$managers = Import-Csv -Path .\test.csv
$usermananger = #()
foreach ($manager in $managers)
{
$getmanagersam = Get-ADUser -Filter "employeeNumber -eq $($manager."Manager User Sys ID")" -Properties SAMAccountName |
Select-Object SAMAccountName
$exportstring = $testmanager |
Select-Object *,#{Name='managerUsername';Expression={"$getmanagersam"}}
$exportstring | Export-Csv -Path .\simpletest.csv -NoTypeInformation
}
As #MathiasR.Jessen mentioned in the comments: you need to expand the SamAccountName property to get just the value. Also, you're overwriting your output CSV with every iteration. Either append to the file, or move the Export-Csv cmdlet outside the loop. The former requires PowerShell v3 or newer, the latter requires that you change the loop to a ForEach-Object loop (or run the foreach loop in a subexpression).
Personally I'd prefer using a pipeline, so I'd pick the latter:
Import-Csv -Path .\test.csv | ForEach-Object {
$acct = Get-ADUser -Filter "employeeNumber -eq $($_.'Manager User Sys ID')" |
select -Expand SamAccountName
$_ | select *,#{Name='managerUsername';Expression={$acct}}
} | Export-Csv -Path .\simpletest.csv -NoTypeInformation
The short answer is to add the -Append option to your export-csv statement to stop it overwriting each time round the loop.
Alternatively move the export outside the loop as follows:
$managers = Import-Csv -Path .\test.csv
$managers|foreach-object{
$getmanagersam = Get-ADUser -Filter "employeeNumber -eq $($_.'Manager User Sys ID')" | select -ExpandProperty SAMAccountName
$_|Select *,#{Name='managerUsername';Expression=$getmanagersam}
} | Export-Csv -Path .\simpletest.csv -NoTypeInformation
Note: looks like #AnsgarWiechers beat me to it :-)
I'm late to the party it looks like, but that rarely stops me... I'm not a huge fan of adding properties via the Select cmdlet, so I'm going to offer an alternative where you pipe the CSV to a ForEach-Object loop (just like the other answers), but inside that you use Add-Member with the -PassThru argument, and then pipe it off to the output file. I will add a new line and indent after the pipes, just to make it easier to read.
Import-Csv -Path ".\test.csv" |
ForEach-Object {Add-Member -InputObject $_ -NotePropertyName 'managerUserName' -NotePropertyValue (Get-ADUser -Filter "employeeNumber -eq $($_.'Manager User Sys ID')").samaccountname -PassThru} |
Export-Csv -Path ".\simpletest.csv" -NoTypeInformation
This should essentially do the exact same thing as the other two answers, it just adds the property differently, because variety is the spice of life! (I saw that on the internet somewhere, so it must be true.)
I am trying to get a list of mailboxes that have a an AD group listed in their permissions.
All the AD groups I am interested in start with the same 3 characters.
I have....
get-mailbox -resultsize unlimited | Get-MailboxPermission | where {$_.user.tostring() -like "xxx*"} | out-file $file -append -noclobber -encoding ascii
but it doesn't seem to put anything in the file
What am I doing wrong?
TIA
Andy
I have a sneaking feeling there will be more questions after this but part of the issue is you loose the mailbox details when they are being passed into the cmdlet Get-MailboxPermission. If you match criteria was a little more refined your output would just be the groups that matched but not to which mailbox.
$file = "c:\temp\test.csv"
$matchPrefix = [regex]::Escape("Ex") # We use escape incase of special charaters in regex. Period would be one to expect.
$regex = "YOURDOMAIN\\$matchPrefix" # Keep those backslashes
Get-Mailbox mc* | ForEach-Object{
$results = $_ | Get-MailboxPermission | Where-Object{$_.User.ToString() -match $regex}
If($results){$_}
} | Select Name,Alias | Export-CSV $file -Append -NoTypeInformation
This will take every mailbox and check each for the presence of the group/user. Using $regex we check each of the located user/groups. If they are present then the -match would return True satisfying the Where block and the mailbox is passed in the pipeline to be exported.
For the export we just send the mailbox name and alias to a csv file specified by $file
Caveats
-Append is available in PowerShell 3.0 which you exchange might not have. I could just be removed.
Assumptions
I am assuming you want just the mailboxes that match the group prefix you specify. If you want the actual groups that match it is possible with a little extra logic. I would like to know if what I suggest is sufficient before I guess more.
This code works, and it is also clear as to which mailbox these permissions belong:
get-mailbox -resultsize 1000 | foreach{
Write-Host $_.PrimarySMTPAddress -ForegroundColor Green;
$permissions = Get-MailboxPermission $_.PrimarySMTPAddress | ?{$_.User -match "Ryan"}
if($permissions){
$permissions | FT -AutoSize;
$_.PrimarySmtpAddress | Out-File C:\Test.txt -append -noclobber -encoding ascii;
$permissions | FT -AutoSize | Out-File C:\Test.txt -append -noclobber -encoding ascii;
}
}
Please note: I checked to see what $_.user.tostring() produces in order to know what I am looking for with respect to the "match" Boolean logic.
I am still on the learning curve with powershell, i currently have the following script:
$users = Get-Acl $Path |
Select-Object -ExpandProperty access |
ft identityreference |
where { $_.identityreference -like "UK\"}
$Path is the location of a particular share on a server. I currently have a CSV file called "test" with about 100 share names on the same server (The first column heading named "ShareNames"), the second column is named "GroupName".
I need to update this script to search through the first column in the CSV file called "test.csv" and push out the appropriate group permission to that share in the second column. I have to also admit the last part of the script does not work :( i am having trouble filtering out a common group name we have as i do not want the whole list of groups for every share only group names that start with ("uk\gro...").
Thank you for any guidance / help
I would choose -match over -like and skip the Format-Table. The following would filter the ACEs on their property IdentityReference using the regex ^UK\\ -- I am assuming that 'UK\' is the domain portion of the group name within the ACEs:
$user = Get-Acl $path |
Select-Object -ExpandProperty access |
Where-Object { $_.IdentityReference -match '^UK\\' }
Then you can ft as desired:
$user | Format-Table
If you need to feed in a CSV of paths, you can pipe an Import-Csv into a ForEach-Object wrapped around the above example.
Import-Csv test.csv |
ForEach-Object {
Write-Output "ACEs on $($_.ShareNames) matching 'UK\'"
Get-Acl $_.ShareNames |
Select-Object -ExpandProperty access |
Where-Object { $_.IdentityReference -match '^UK\\' }
}
I'm still not clear on how you intend to populate the "GroupName" column in the output as there could be multiple entries for groups beginning with 'UK\'.