One different Folder per Line - sorting

Im actually listing the folder Permissions of some Exhange Mailboxes with the following exchange command:
get-mailboxfolder -recurse | get-mailboxfolderpermissions | ft
Now the Output looks like this:
RunspaceId FolderName User AccessRights Identity IsValid
---------- ---------- ---- ------------ -------- -------
0a6a00b7-859a-4297-b03f-41... Top of Information Store Default {None} Default True
0a6a00b7-859a-4297-b03f-41... Top of Information Store Anonymous {None} Anonymous True
0a6a00b7-859a-4297-b03f-41... Calendar Default {AvailabilityOnly} Default True
0a6a00b7-859a-4297-b03f-41... Calendar Anonymous {None} Anonymous True
0a6a00b7-859a-4297-b03f-41... Contacts Default {None} Default True
0a6a00b7-859a-4297-b03f-41... Contacts Anonymous {None} Anonymous True
0a6a00b7-859a-4297-b03f-41... Deleted Items Default {None} Default True
0a6a00b7-859a-4297-b03f-41... Deleted Items Anonymous {None} Anonymous True
0a6a00b7-859a-4297-b03f-41... Drafts Default {None} Default True
As you see, the output shows for each user that is set, one time the same folder.
I would like to have only one row per folder with the listing of all User. Something like that:
RunspaceId FolderName User AccessRights Identity IsValid
---------- ---------- ---- ------------ -------- -------
0a6a00b7-859a-4297-b03f-41... Top of Information Store Default, Anonymous {None} Default True
0a6a00b7-859a-4297-b03f-41... Calendar Default, Anonymous {AvailabilityOnly} Default True

Is this what you're looking for? You need to specify how you want to handle combining AccessRights, Identity etc. I made a sample to give you an idea of how to do this, but you need to modify if you want to add extra fields etc.
I don't have access to Get-MailboxFolder or Get-MailboxFolderPermissions, so the output is what I believe it would look like. I'm not 100% sure about the AccessRights-part as I don't know the datatype.
$combinedUsers = #{n="Users";e={($_.Group | Select-Object -ExpandProperty User) -join ', '}}
$combinedAccessRights = #{n="AccessRights";e={($_.Group | Select-Object -ExpandProperty AccessRights) -join ', '}}
get-mailboxfolder -recurse |
get-mailboxfolderpermissions |
Group-Object FolderName |
Select-Object #{n="FolderName";e={$_.Name}}, $combinedUsers, $combinedAccessRights
FolderName Users AccessRights
---------- ---- ------------
Top of Information Store Default, Anonymous {None}, {None}
Calendar Default, Anonymous {AvailabilityOnly}, {None}

Related

Composite index is not getting registered. It is struck in ENABLED status forever

I'm running janusgraph with cassandra and ES as backend. Following is my script used in building the composite index.
JanusGraphManagement mgmt = graph.openManagement()
def addPropertyKeyIfNotExists(JanusGraphManagement mgmt, String keyName, Class keyType, org.janusgraph.core.Cardinality cardinalityType) {
if (!mgmt.containsPropertyKey(keyName)) mgmt.makePropertyKey(keyName).dataType(keyType).cardinality(cardinalityType).make()
}
vertexCompositeIndexName = "vertex_data_composite"
addPropertyKeyIfNotExists(mgmt, "vertex_id", String.class, org.janusgraph.core.Cardinality.SINGLE)
addPropertyKeyIfNotExists(mgmt, "tenant", String.class, org.janusgraph.core.Cardinality.SINGLE)
addPropertyKeyIfNotExists(mgmt, "entity", String.class, org.janusgraph.core.Cardinality.SINGLE)
addPropertyKeyIfNotExists(mgmt, "entity_type", String.class, org.janusgraph.core.Cardinality.SINGLE)
addPropertyKeyIfNotExists(mgmt, "first_seen_at", Long.class, org.janusgraph.core.Cardinality.SINGLE)
addPropertyKeyIfNotExists(mgmt, "first_seen_source", String.class, org.janusgraph.core.Cardinality.SINGLE)
addPropertyKeyIfNotExists(mgmt, "last_seen_at", Long.class, org.janusgraph.core.Cardinality.SINGLE)
vertexId = mgmt.getPropertyKey("vertex_id")
tenant = mgmt.getPropertyKey("tenant")
entity = mgmt.getPropertyKey("entity")
entityType = mgmt.getPropertyKey("entity_type")
firstSeenAt = mgmt.getPropertyKey("first_seen_at")
firstSeenSource = mgmt.getPropertyKey("first_seen_source")
lastSeenAt = mgmt.getPropertyKey("last_seen_at")
if (!mgmt.containsGraphIndex(vertexCompositeIndexName)) {
mgmt.buildIndex(vertexCompositeIndexName, Vertex.class).
addKey(vertexId).
addKey(tenant).
addKey(entity).
addKey(firstSeenSource).
addKey(entityType).
addKey(firstSeenAt).
addKey(lastSeenAt).
buildCompositeIndex()
}
println(mgmt.printSchema())
mgmt.commit()
mgmt.close()
graph.close()
graph = JanusGraphFactory.open("/etc/opt/janusgraph/janusgraph.properties")
mgmt = graph.openManagement()
mgmt.awaitGraphIndexStatus(graph, vertexCompositeIndexName).call()
It has been more than an hour and still the composite index status is in ENABLED. It never became REGISTERED.
gremlin> mgmt.printSchema()
==>------------------------------------------------------------------------------------------------
Graph Index (Vertex) | Type | Unique | Backing | Key: Status |
---------------------------------------------------------------------------------------------------
vertex_data_composite | Composite | false | internalindex | vertex_id: ENABLED |
| | | | tenant: ENABLED |
| | | | entity: ENABLED |
| | | | first_seen_source: ENABLED |
| | | | entity_type: ENABLED |
| | | | first_seen_at: ENABLED |
| | | | last_seen_at: ENABLED |
---------------------------------------------------------------------------------------------------
I see the following in my logs
jce-janusgraph | 7953215 [gremlin-server-worker-1] INFO org.janusgraph.graphdb.database.management.GraphIndexStatusWatcher - Some key(s) on index vertex_data_composite do not currently have status(es) [REGISTERED]: entity_type=ENABLED,vertex_id=ENABLED,first_seen_at=ENABLED,first_seen_source=ENABLED,last_seen_at=ENABLED,tenant=ENABLED,entity=ENABLED
jce-janusgraph | 7953216 [gremlin-server-worker-1] INFO org.janusgraph.graphdb.database.management.GraphIndexStatusWatcher - Timed out (PT1M) while waiting for index vertex_data_composite to converge on status(es) [REGISTERED]
Composite index not used while querying.
gremlin> g.V().has("vertex_id","ddd").profile()
==>Traversal Metrics
Step Count Traversers Time (ms) % Dur
=============================================================================================================
JanusGraphStep([],[vertex_id.eq(ddd)]) 49.819 100.00
constructGraphCentricQuery 15.133
constructGraphCentricQuery 0.074
GraphCentricQuery 19.326
\_condition=(vertex_id = ddd)
\_orders=[]
\_isFitted=false
\_isOrdered=true
\_query=[]
scan 17.445
\_query=[]
\_fullscan=true
\_condition=VERTEX
>TOTAL - - 49.819 -
We see following in the logs
jce-janusgraph | 339186 [gremlin-server-session-1] WARN org.janusgraph.graphdb.transaction.StandardJanusGraphTx - Query requires iterating over all vertices [(vertex_id = ddd)]. For better performance, use indexes
From JanusGraph index lifecycle you can see that your index is already ENABLED and can be used. You don't need to wait for the index to be REGISTERED in this particular case.
Normally index transition in the following order:
INSTALLED - The index is installed in the system but not yet registered with all instances in the cluster.
REGISTERED - The index is registered with all instances in the cluster but not (yet) enabled.
ENABLED - The index is enabled and in use.
DISABLED - The index is disabled and no longer in use.
Usually after your created the index it becomes INSTALLED, then you wait until all JanusGraph nodes pick up the newly created index and it changes the status to REGISTERED. As soon as it is REGISTERED (meaning all JanusGraph nodes know about it) you can enable the index or start REINDEX process which automatically enables the index after reindex is finished.
So, why your index changed the status to ENABLED immediately instead of transitioning from state to state? That's because JanusGraph has a special optimization which enables newly created indexes immediately if all it's keys were created in the same transaction. In your situation all properties were created in the same transaction (most likely). Thus, your index is now ENABLED. You don't need to do anything else because your index is already in use.
P.S. As a side topic, not directly related to this use-case but related to the issue when the index cannot change it's state from INSTALLED to REGISTERED you can checkout the following suggestions.

Email Account Lock Out Notification - Powershell

I will like to email the SysAdmin event id 4625 (Account lockout) occurs.
I have the following code, and it works just find. See output attached:
Current code:
$AccountLockOutEvent = Get-EventLog -LogName "Security" -InstanceID 4625 -Newest 1
$LockedAccount = $($AccountLockOutEvent.ReplacementStrings[0])
$AccountLockOutEventTime = $AccountLockOutEvent.TimeGenerated
$AccountLockOutEventMessage = $AccountLockOutEvent.Message
$messageParameters = #{
Subject = "Account Locked Out: $LockedAccount"
Body = "Account $LockedAccount was locked out on $AccountLockOutEventTime..`n`nEvent
Details:`n`n$AccountLockOutEventMessage"
From = ""
To = ""
SmtpServer = ""
}
Send-MailMessage #messageParameters
Question to Powershell gurus
1 - How can I capture the exact reason for lockout instead of %%2313 and other information such as the samaccountname. Instead using Account locked out s-1-0-0 in the subject line, I want to see the Account name there.
2 - is there a way get the ADuser information so that we can email the user at thesame time informing that that their account was locked out to contact the SysAdmin to unlock the account?
You can use this snippet to get an output that contains the fields you need.
SubjectUserName and SubjectDomainName.
$events = Get-WinEvent -FilterHashtable #{logname='Security'; ID=4625; } -MaxEvents 1
$event = $events
[xml]$eventXML = [xml]$Event.ToXml()
$eventXML.Event.EventData.Data
Output will look like this.
Name #text ---- -----
SubjectUserSid S-0-0-00-0000000000-0000000000-0000000000-0000
SubjectUserName MyUsername
SubjectDomainName MyHostname
SubjectLogonId 0x00000000
PrivilegeList SeSecurityPrivilege

Laravel : login from one subdomain to another subdomain : session issue

I am using Sentry on laravel 4.2 in one application with muti-subdomain (every domain have different users) : i want to login from one subdomain(domain-a.maindomain.com) to another subdomain(domain-b.maindomain.com) without persisting session across subdomain.
Any one have idea how can i achieve this with laravel
i think Since the Laravel authentication system uses cookies to manage the session, you actually need to login the user on each subdomain you're going to use. To avoid that, you can use another session driver like database. and what #SUB-HDR give you in his comment is a good way too do it.
I'm not familiar with Laravel before version 5.1 but there is part of the documentation which relates to authentication:
https://laravel.com/docs/4.2/security
$user = User::find(1);
Auth::login($user);
With this you may be able to authenticate a user from one of your domains to the other. You would need to pass something from the first domain to the second domain which is a unique common attribute between the two user models and then authenticate the matching user.
in (php / mysql) we can made a row called IslogedIn(or something else you prefer) in All your Databases so they''ll look like :
//---------------------------------------------
// (main database) --> site1.com
// ------------------------------------------
// | id | username | password | IslogedIn |
// |-----|-----------|----------|-------------|
// | 1 | jhony | pass | 0 |
// |-----|-----------|----------|-------------|
//---------------------------------------------
// (2nd database) --> site2.com
// ------------------------------------------
// | id | username | password | IslogedIn |
// |-----|-----------|----------|-------------|
// | 1 | jhony | pass | 1 |
// |-----|-----------|----------|-------------|
here for example we see the user is logged in 2nd database
so the value will be : IslogedIn = 1
and we gonna use that in all our domains and from "login.php" (in Laravel it can be somthing else) , from "login.php" we mark IslogedIn = 1 if the user logged in by using some mysql orders .
after that we connect all databases using a scrip page and name it something like : 'checkout.php' in both domains folders and write in it :
1 - for old php versions :
$Db_Main_con = mysql_connect($hostname, $username, $password );
$Db_2nd_con = mysql_connect($hostname, $username, $password , true);
//-------------------------------------------------------------
$Db_Main_Select = mysql_select_db("Database_name1", $Db_Main_con);
$Db_2nd_Select = mysql_select_db("Database_name2", $Db_2nd_con );
//-------------------------------------------------------------
$Db_main = mysql_query("select * from users where id = :id", $Db_Main_Select);
$Db_2nd = mysql_query("select * from users where id = :id", $Db_2nd_Select);
2 - for new version is Generally similar only some changes in the past code , such as mysql to mysqli . read this article : mysqli_connect
and I'm not familiar with Laravel so ofc you change the "$host_main_name" and "$username" and ( table name )..... etc to feet your script
and from every db call the row : (IslogedIn) in a $string.
then we go to check if the user is Logedin in all Db we have :
if ( $Db_Main->IslogedIn || $Db_2nd->IslogedIn )
{
// ----->> your login code or relogin code here
// + sessions and cookies and reloud link and all other stuff
}
then we close the script with $Db_Main->close(); $Db_2nd->close(); .... etc when the checkout is end .

Find accounts innactive for X days in specific OUs

I am trying to get a PowerShell script running that will display a list of all users who have been inactive (or not logged in) in x days. That part was easy enough to find and modify a script for, but I am having trouble setting it so I can specify only certain OUs and sub OUs within the domain. This is what I have so far, though I think I might have to use another method to accomplish this:
#Import Ad Module
Import-Module ActiveDirectory
#SearchBase
$searchB = (Get-Content -Path C:\scripts\ous.txt)
#Time accounts have been inactive
$tSpan = "145"
Search-ADAccount -SearchBase $searchB -AccountInactive -UserOnly -Timepsan $tSpan |
Where {($_.DistinguishedName -notlike "specific sub-ou I don't want to check")} |
FT name,ObjectClass -A
The text file is in the format:
OU=first ou,OU=Parent OU,DC= thisDC,DC=dc,DC=DC
OU=third ou,OU=Parent OU,DC= this DC,DC=dc,DC=DC
OU=fourthou,OU=Parent OU,DC= thisDC,DC=dc,DC=DC
When I run this I get an error
Search-ADAccount : Directory object not found
Looks like you have a type mismatch in your -SearchBase parameter.
See Get-Help Search-ADAccount
Note that the value type for -SearchBase is string. You have three OUs in your text file, so Get-Content on that file is going to produce a string array (string[]).
Since the -SearchBase parameter will only accept a single value, you'll need to foreach through the OU list, giving on one OU at a time:
foreach ($OU in $SearchB)
{
search-adaccount -searchbase $OU -accountinactive -useronly -timepsan $tSpan.....
}

Powershell - Add (default display) object property values from pipe to string

Update 2: I ended up figuring this out while writing it. I figured I'd post it for anyone else muddling through. See sub-heading 'Resolution - Get only default properties', or the answer. Please feel free to respond with alternate (especially better!) methods or comments.
Update 1: I started out without a way to do this, I've since found a way for ALL properties. I've left the build-up for anyone else confused like I was, but my current problem is that I want JUST the default display properties - see sub-heading 'Get all Properties'
Let's say I have a collection of objects in powershell - the specific example I'm working with is a collection of events acquired using the get-winevent cmdlet.
Does anyone know an elegant way to get the values of all the (default) properties of each object, from the pipeline, and add them to the end of a string? Especially a way that doesn't involve needing to know which properties you want.
For example, using variable $events containing some event log entries, if I simply call $events powershell will make some assumptions about the properties I want and format them as a list:
PS C:\> $events
TimeCreated ProviderName Id Message
----------- ------------ -- -------
11/09/2014 3:59:... Microsoft-Window... 4634 An account was l...
11/09/2014 3:58:... Microsoft-Window... 4634 An account was l...
However, if I try to precede the returned entries with a string, I get the property names rather than values:
PS C:\> $events | %{"NEW RECORD" + $_}
NEW RECORDSystem.Diagnostics.Eventing.Reader.EventLogRecord
NEW RECORDSystem.Diagnostics.Eventing.Reader.EventLogRecord
PS C:\> $events | %{"NEW RECORD" + $_.properties}
NEW RECORDSystem.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.E
venting.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty S
ystem.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Rea
der.EventProperty
The easiest work around I could think of involved using (and therefore knowing) the property values, and also losing the notation that format-table or format-list would provide:
PS C:\> $events | %{"NEW RECORD - TimeCreated: " + $_.TimeCreated + "; ProviderName: "`
+ $_.ProviderName + "; ID: " + $_.ID + "; Message: " + $_.message}
NEW RECORD - TimeCreated: 09/11/2014 15:58:08; ProviderName: Microsoft-Windows-
Security-Auditing; ID: 4672; Message: Special privileges assigned to new logon.
Subject:
Security ID: S-*-*-**-*********-**********-**********-*****
Account Name: **********
Account Domain: **********
Logon ID: 0x**********
Privileges: SeSecurityPrivilege
Get all Properties
So I've discovered I CAN get ALL the properties, and their names, like this:
PS C:\> $events | %{"NEW RECORD" + ($_.psobject.properties | %{$_.name ; ":" ; $_.value})}
NEW RECORDMessage : Special privileges assigned to new logon.
Subject:
Security ID: S-*-*-**-*********-**********-**********-*****
Account Name: **********
Account Domain: **********
Logon ID: 0x**********
Privileges: SeSecurityPrivilege Id : 4672 Version : 0 Qualifiers :
Level : 0 <and so on>
However, I'm now pulling a bunch of stuff the consumers of my data won't need, since I only need the default properties and their names, plus a self-defined delimiter.
Is anyone aware of a notation that will return all values of all default display properties without said properties needing to be spelled out? Either a generic container for values (eg. $_.properties.value, though I tried that and it didn't work), or something like expand-property only without needing to specify a particular property name?
Resolution - Get only default properties
So it turns out I was overthinking this. FOREACH (%{}) can obviously preserve data from the pipeline across statements, so if I use two statements I can achieve the desired effect:
PS C:\> $events | format-list | %{"NEW RECORD" ; $_}
NEW RECORD
Message : An account was successfully logged on.
<and etc>
I answered this while writing it, the details are above. In order to collect all properties from an object and their values, and include both as part of a string:
PS C:\> $events | %{"NEW RECORD" + ($_.psobject.properties | %{$_.name ; ":IMASTRING:" ; $_.value})}
The above method owes a lot to the answer by Shay Levy to this question.
To include only the default properties and their values, preceded by a string:
PS C:\> $events | format-list | %{"NEW RECORD" ; $_}
To include all properties and their values, preceded by a string but retain the default formatting:
PS C:\> $events | select-object * | format-list | %{"NEW RECORD"; $_}
I think you've done things the easy and maybe best way for your situation. There actually is a way to know the names of the default properties
PS Scripts:\> $x = gwmi -Class win32_operatingsystem
PS Scripts:\> $x.psstandardmembers
PSStandardMembers {DefaultDisplayPropertySet}
PS Scripts:\> $x.psstandardmembers.DefaultDisplayPropertySet
ReferencedPropertyNames : {SystemDirectory, Organization, BuildNumber, RegisteredUser...}
MemberType : PropertySet
Value : DefaultDisplayPropertySet {SystemDirectory, Organization, BuildNumber, RegisteredUser,
SerialNumber, Version}
TypeNameOfValue : System.Management.Automation.PSPropertySet
Name : DefaultDisplayPropertySet
IsInstance : False
PS Scripts:\> $x.psstandardmembers.DefaultDisplayPropertySet.ReferencedPropertyNames
SystemDirectory
Organization
BuildNumber
RegisteredUser
SerialNumber
Version
This is the post that I found this information on PSStandard Members.

Resources