Identify all users with "full access" and "send on behalf" access to each shared mailbox where the user is disabled - exchange-server

We have the script here in the company when the user is fired, for a few months we leave the user disabled and do not delete it, however I need to clean our shared mailboxes and check which of these unblown users still have access to these mailboxes
Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize:Unlimited | Get-MailboxPermission |Select-Object Identity,User,AccessRights | Where-Object {($_.user -like '#')}|Export-Csv C:\Temp\sharedfolders.csv -NoTypeInformation
I already have my script that checks all shared mailboxes, but I need to create a kind of filter where the results show me only users who are no longer active in AD, someone can help me, please?

I think this is what you are looking for.
$mailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize unlimited
$mailboxes | Get-MailboxPermission | ForEach-Object{
$perm = $_
$ADuser = Get-ADUser $perm.user.securityidentifier.value
$perm | Add-Member -MemberType NoteProperty -Name UserEnabled -Value $ADuser.Enabled
$perm
} | Select-Object Identity, User, AccessRights, UserEnabled | Where-Object { ($_.user -like '#') -and $_.UserEnabled -eq $false } | Export-Csv C:\Temp\sharedfolders.csv -NoTypeInformation
Note it does require the Active Directory module to use the Get-ADuser command.

Related

Is it possible to have powershell curl output only the content part? [duplicate]

In PowerShell, how do you get an object's property value by specifying its name (a string)? I want something like the following:
$obj = get-something
# View the object's members:
$obj | gm
# I could retrieve a property by doing so:
write-host $obj.SomeProp
# But for many purposes, I would really want to:
write-host $obj | Get-PropertyByName "SomeProp"
Is there something similar to "Get-PropertyByName" in PowerShell?
Sure
write-host ($obj | Select -ExpandProperty "SomeProp")
Or for that matter:
$obj."SomeProp"
Expanding upon #aquinas:
Get-something | select -ExpandProperty PropertyName
or
Get-something | select -expand PropertyName
or
Get-something | select -exp PropertyName
I made these suggestions for those that might just be looking for a single-line command to obtain some piece of information and wanted to include a real-world example.
In managing Office 365 via PowerShell, here was an example I used to obtain all of the users/groups that had been added to the "BookInPolicy" list:
Get-CalendarProcessing conferenceroom#example.com | Select -expand BookInPolicy
Just using "Select BookInPolicy" was cutting off several members, so thank you for this information!
You can get a property by name using the Select-Object cmdlet and specifying the property name(s) that you're interested in. Note that this doesn't simply return the raw value for that property; instead you get something that still behaves like an object.
[PS]> $property = (Get-Process)[0] | Select-Object -Property Name
[PS]> $property
Name
----
armsvc
[PS]> $property.GetType().FullName
System.Management.Automation.PSCustomObject
In order to use the value for that property, you will still need to identify which property you are after, even if there is only one property:
[PS]> $property.Name
armsvc
[PS]> $property -eq "armsvc"
False
[PS]> $property.Name -eq "armsvc"
True
[PS]> $property.Name.GetType().FullName
System.String
As per other answers here, if you want to use a single property within a string, you need to evaluate the expression (put brackets around it) and prefix with a dollar sign ($) to declare the expression dynamically as a variable to be inserted into the string:
[PS]> "The first process in the list is: $($property.Name)"
The first process in the list is: armsvc
Quite correctly, others have answered this question by recommending the -ExpandProperty parameter for the Select-Object cmdlet. This bypasses some of the headache by returning the value of the property specified, but you will want to use different approaches in different scenarios.
-ExpandProperty <String>
Specifies a property to select, and indicates that an attempt should
be made to expand that property
https://technet.microsoft.com/en-us/library/hh849895.aspx
[PS]> (Get-Process)[0] | Select-Object -ExpandProperty Name
armsvc
powershell variables
Try this :
$obj = #{
SomeProp = "Hello"
}
Write-Host "Property Value is $($obj."SomeProp")"
Here is an alternative way to get an object's property value:
write-host $(get-something).SomeProp
$com1 = new-object PSobject #Task1
$com2 = new-object PSobject #Task1
$com3 = new-object PSobject #Task1
$com1 | add-member noteproperty -name user -value jindpal #Task2
$com1 | add-member noteproperty -name code -value IT01 #Task2
$com1 | add-member scriptmethod ver {[system.Environment]::oSVersion.Version} #Task3
$com2 | add-member noteproperty -name user -value singh #Task2
$com2 | add-member noteproperty -name code -value IT02 #Task2
$com2 | add-member scriptmethod ver {[system.Environment]::oSVersion.Version} #Task3
$com3 | add-member noteproperty -name user -value dhanoa #Task2
$com3 | add-member noteproperty -name code -value IT03 #Task2
$com3 | add-member scriptmethod ver {[system.Environment]::oSVersion.Version} #Task3
$arr += $com1, $com2, $com3 #Task4
write-host "windows version of computer1 is: "$com1.ver() #Task3
write-host "user name of computer1 is: "$com1.user #Task6
write-host "code of computer1 is: "$com1,code #Task5
write-host "windows version of computer2 is: "$com2.ver() #Task3
write-host "user name of computer2 is: "$com2.user #Task6
write-host "windows version of computer3 is: "$com3.ver() #Task3
write-host "user name of computer3 is: "$com1.user #Task6
write-host "code of computer3 is: "$com3,code #Task5
read-host

In Powershell how can I remove the first x number of characters from Get-ADUser results?

I have a list of results from Get-ADUser giving me all users in an OU. The format of the output username is '-prefix-username'. I need to remove the 7 character '-prefix-' and then conduct another Get-ADUser lookup against the remaining 'username' portions. The issue I'm finding is that if I run just the second Get-ADUser lookup where I set $User as just one specific '-prefix-username' it works fine but when I try to process a list I either get an error where there seems to be space after the trimmed username (txt format list - Get-ADUser : Cannot find an object with identity: 'user ' under:) or the username includes a " that I can't remove from the end of the username (csv format list - Get-ADUser : Cannot find an object with identity: 'user"').
So far I have:
get-ADUser -Filter * -SearchBase 'OU=SomeOU' -SearchScope 2 |
Select SAMAccountName |
Out-File C:\Temp\UserList.txt
$UserList = (Get-Content C:\Temp\UserList.txt)
$StandardUsers = ForEach($User in $UserList) {
Write-Host "Now checking $User"
Get-ADUser $User.Substring(7) -Properties * |
Select-object DisplayName, UserPrincipalName, Mail, Manager,EmployeeID
}
$StandardUsers | Out-File -FilePath C:\Temp\StandardUserList.txt
First thing to mention is that if you create the list using Select -ExpandProperty SAMAccountName, you would only get SamAccountnames in the file.
Having said that, why bother with an 'in-between' file at all and simply do:
# By default, Get-ADUser returns these properties:
# DistinguishedName, Enabled, GivenName, Name, ObjectClass, ObjectGUID, SamAccountName, SID, Surname, UserPrincipalName
# Only ask for properties that are not already in this list.
Get-ADUser -Filter * -SearchBase 'OU=SomeOU' -SearchScope 2 -Properties DisplayName, EmailAddress, Manager, EmployeeId |
Select-Object DisplayName, UserPrincipalName, EmailAddress, Manager,EmployeeID |
Set-Content -Path 'C:\Temp\StandardUserList.txt'
You are likely having issues with saving it to a file (where it gets formatted) and then reading it back in. The formatting could be adding " and reading a newline (which you think is a space) character. If you really need to save it then do the following (else just hook up the pipelines):
$userList = Get-ADUser -Filter * -SearchBase 'OU=SomeOU' -SearchScope 2 |
Select-Object SAMAccountName
$userList |
Out-File C:\Temp\UserList.txt
$standardUsers = $userList |
Select-Object -ExpandProperty SAMAccountName -PipelineVariable user |
ForEach-Object {
Write-Host "Now checking $user"
$userWithoutPrefix = ($user -Replace '^-prefix-','') -Replace '(\w|\n)$','' # to use a more advanced version of the suggestion by #Avshalom
Get-ADUser $userWithoutPrefix -Properties * | Write-Output
} |
Select-Object DisplayName, UserPrincipalName, Mail, Manager, EmployeeID
$standardUsers | Out-File -FilePath C:\Temp\StandardUserList.txt

How can i get an overview of UWP registered URIs and aliases?

I want to use the "URI style launching" for UWP apps (for example: MS ToDo) from a win32 Application, command line or UWP apps.
UWP has a specific shell URI-Schemas available to launch them.
For example you can press win+R and enter ms-todo: and MS ToDo will start.
Respectively open cmd and enter start ms-todo: and MS ToDo will start.
How can i get a list with all local available URIs?
tl;dr
They are listed in Settings > Apps > Default Apps > Choose default apps by protocol
Getting details for all apps with Powershell
$result = [System.Collections.ArrayList]#();
foreach ($appx in Get-AppxPackage)
{
$location = $appx.InstallLocation
$manifest = "$location\AppxManifest.xml"
if($location -ne $null -and (Test-Path $manifest -PathType Leaf))
{
[xml]$xml = Get-Content $manifest
$ns = new-object Xml.XmlNamespaceManager $xml.NameTable
$ns.AddNamespace("main", "http://schemas.microsoft.com/appx/manifest/foundation/windows10")
$ns.AddNamespace("uap", "http://schemas.microsoft.com/appx/manifest/uap/windows10")
$ns.AddNamespace("uap3", "http://schemas.microsoft.com/appx/manifest/uap/windows10/3")
$ns.AddNamespace("uap5", "http://schemas.microsoft.com/appx/manifest/uap/windows10/5")
$uriElements = $xml.SelectNodes("//uap:Extension[#Category = 'windows.protocol']/uap:Protocol/#Name", $ns)
$uris = $uriElements | select -ExpandProperty '#text'
$appIds = $xml.SelectNodes("//main:Application/#Id", $ns) | select -ExpandProperty '#text'
if ($appIds.Count -eq 0) {
continue;
}
$aliases = $xml.SelectNodes("//main:Extensions/uap5:Extension[#Category = 'windows.appExecutionAlias']/uap5:AppExecutionAlias/uap5:ExecutionAlias/#Alias", $ns) | select -ExpandProperty '#text'
#$result[$appx.Name] = $uris
$tmp = New-Object -TypeName PSObject
$tmp | Add-Member –MemberType NoteProperty –Name Name –Value "$($appx.Name)"
$tmp | Add-Member –MemberType NoteProperty –Name URIs –Value ($uris -join "`n")
$tmp | Add-Member –MemberType NoteProperty –Name Aliases –Value ($aliases -join "`n")
$tmp | Add-Member –MemberType NoteProperty –Name Package –Value "$($appx.PackageFamilyName)"
$tmp | Add-Member –MemberType NoteProperty –Name AppIds –Value ($appIds -join "`n")
$tmp | Add-Member –MemberType NoteProperty –Name Folder –Value $appx.InstallLocation
$null = $result.Add($tmp)
}
}
$result | Sort-Object -Property Name | Out-GridView
Result
The manual way for a single App:
I'm only aware of a slighly cumbersome manual way have to do do for every single app.
In this case "Microsoft.Todos"
Execute
Get-AppxPackage -Name Microsoft.Todos
Read Property "InstallationLocation"
C:\Program Files\WindowsApps\Microsoft.Todos_2.27.32662.0_x64__8wekyb3d8bbwe
Open AppxManifest.xml
C:\Program Files\WindowsApps\Microsoft.Todos_2.27.32662.0_x64__8wekyb3d8bbwe\AppxManifest.xml
Look for protocol entries:
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="ms-to-do">
<uap:DisplayName>ms-resource:app_name_ms_todo</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="ms-todo">
<uap:DisplayName>ms-resource:app_name_ms_todo</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
As you can see "ms-to-do" and "ms-todo" are the associated URIs.

Lazy loading in powershell?

Can we defer a variable initialization untill it is needed ?
What I would like to do is predefine some variables in my profile that will contain a list of AD computer:
let's say I want:
$OU1_workstation to be fill with computers found in OU=workstations,OU=OU1,dc=domain,dc=com
$OU2_workstation fill with computers found in
OU=workstations,OU=OU2,dc=domain,dc=com and so on...
I use the following script to do it but it takes 30sec to compute, so currently I can't put that in my profile...
Get-ADOrganizationalUnit -SearchScope onelevel -Filter "*" -Properties "name","distinguishedname" |%{
set-Variable -Name "$($_.name)_workstation" -value (Get-ADComputer -Searchbase "OU=workstations,$($_.Distinguishedname)" -Filter * )
}
What options are available in powershell ?
Finally, based on #Richard's reply of a previous question of mine, I've chosen the following path to achieve some sort of lazy loading : using a scriptproperty of a PSCustomObject.
So I can put this in my profile
#requires -module activedirectory
$server=New-Object PSCustomObject
Get-ADOrganizationalUnit -SearchScope onelevel -Filter "*" -Properties "name","distinguishedname" |
?{
$_.name -notmatch 'Administrateurs|Administration|Comptes de deploiement|Contacts|Domain Controllers|Groupes|Serveurs|Services'
} |
%{
$OU=$_.name
$s=[scriptblock]::Create("Get-ADComputer -SearchBase ""OU=servers,OU=$OU,DC=domain,DC=com"" -Filter 'name -notlike "" *old""' |select -expand name")
$server| Add-Member -MemberType ScriptProperty -name $OU -value $s -Force
}
then when needed I can call $server.OU1 to get all server under this OU, $server.OU2 etc...

Get Logged on Users from a List of Computer Names

I wanted to extract a list of users logged on to remote pc, the ps names would be fed in using a .csv file.
I was able to get a command
Get-WmiObject Win32_LoggedOnUser -ComputerName $Computer | Select Antecedent -Unique
to query the user names, could any one help me more on how to write this code?
Assuming the csv file contains a ComputerName header:
Import-Csv computers.csv | Foreach-Object{
Get-WmiObject Win32_LoggedOnUser -ComputerName $_.ComputerName | Select-Object __SERVER,Antecedent -Unique | Foreach-Object {
$domain,$user = [regex]::matches($_.Antecedent,'="([^"]+)"') | Foreach-Object {$_.Groups[1].Value}
$_ | Select-Object __SERVER,#{Name='Domain';Expression={$domain}},#{Name='User';Expression={$user}}
}
}

Resources