Monday, December 31, 2012
Description of Jannah (Paradise, Heaven) - Tawfique Chowdhury
To begin, the Sheikh posed the question of what is our ultimate purpose of our creation. The answer of the participants followed along the lines of what is outlined in the Quran where it is stated that Man and Jinn were created for the worship of Allah. The Sheikh continued asking if this was the ultimate purpose of our creation? If this was it, why is it that we are not required to fast, pray, give charity, etc when we are in Jannah? He stated that his opinion on the matter is that we were created for the purpose of entering Jannah and that Allah loves his creation.
To illustrate the love of Allah for his servant, he quoted Sufian Ath-Athari (spelling?), who once said something to the effect of: He would rather have Allah as a judge over him than have his parents as a judge over him. As the love of Allah for his servant exceeds that of the love of a parent for a child.
(random point of note) The purpose of ibaadah in this world could be said that it is our showing thankfulness for the fact that Allah created Jannah for us and wants us to be in it.
In another narration related to Jannah, there was a companion by the name of Haritha who was on the way to the battle of badr, but died in route due to an accident. As he did not die as a matyr in battle, his mother was distressed about what his state would be in the hereafter. The prophet (saw) said to her (paraphrasing here), Woe to you oh mother of Haritha, do you think there is only one Jannah? There are hundreds of Jannah's, and Haritha is in the highest.
---Side note here. When the phrase "Woe to you" is used by the prophet (pbuh), it can be either a sign of anger, or a sign of happiness (depending on the circumstance)
In reference to the levels of jannah, the scholars are of two opinions. One opinion is that there are 100 levels and this is based on an authentic hadith that states the specific number. The other opinion stated that there was (5600?, didn't catch the exact number) levels, and this was based on the hadith where people are told to recite the quran as they recited it in the world and with each verse they would raise on level in the heavens. So the number here relates to # of verses? Allah knows best.
As for the levels themselves, the difference between one level and the next is like the heavens and the earth is in this world. When one raises a level he will think he has gone so far that there couldn't be any more levels above them.
As to how to get to Jannah, the Sheikh referenced a hadith where the prophet stated 3 times, Is not the price of Jannah expensive? In relation to this we need to understand it cannot be bought. We need to perform actions to make us worth of it. We can't just say we love Allah, because speaking such words does not guarantee Allah loves us in return. The sheikh then referenced the verse of the Quran (3:31):
Sahih International: Say, [O Muhammad], "If you should love Allah , then follow me, [so] Allah will love you and forgive you your sins. And Allah is Forgiving and Merciful."
To emphasis how special Jannah is, the Sheikh related a hadith that mentions that Allah has created 3 things with his own hands:
1) The Taurat
2) Adam (As)
3) Jannah
In the description of Jannah, we start out on the big plain in front of Jannah. There will be 120 rows of people; not old (our age is changed to 33 years old), we have the beauty of Yusuf, and we are 60ft tall/7ft wide which is the size of Adam (as). Additionally there is no hijab and no beard (These are tests of this life. And in relation to modesty of sisters, men will just not be able to see them). Of the 120 rows, 80 will be from the ummah of Muhammad (saw), and the other 40 will be from people of the earlier nations. In the rows will also be Jinn, though one point of note here is that in Jannah, we can see the Jinn and they cannot see us [reverse of this world].
Servants (in the form of children), who look like scattered pearls will come out. They will give you the clothes of Jannah and the drinks of Jannah (to prepare you to be in an appropriate state for your entry). The Clothes are made of the Tuba tree's bark. You will also be given ornaments of gold and other precious materials.
The smell of Jannah is so great that we won't be able to hold ourselves back. It can be smelled at the distance of 500 years travel. (one note from myself to those reading this. Think of this along with the hadiths that mention that the people that do certain actions will not even smell the fragrance of Jannah; may Allah protect us).
Jannah itself is held by 70,000 rings. Each ring is held by 70,000 angels.
There are 8 gates to Jannah, and the distance between each gate is 500 years of travel. The gates have huge signs with names carved in stone. The list will be the names of those allowed to enter through this gate. Each gate will have a spring that will contain the drinks of Jannah. The people will rush between gates looking for where they will be allowed to enter. Fragrance of Jannah will be blown down from the gates. The sheikh did not mention all of the gates, but specifically pointed out four: 1) Jihad, 2) fasting, 3) goodness to parents?, 4) charity
When you find a gate that you are allowed to enter, an Angel will permit you to come in. When you enter, you will look up and see rows of Angels of all types (2 wings, 4 wings, etc etc). The angels will greet you with the greetings of peace. You will see flashes of lightning behind the angles that are so severe that you can't look at them. You will ask the servants of Jannah what they lightning is and they will just smile, turn away and talk to the other servants. An angel will inform you that the lightning is caused by the smiles of your wives in Jannah.
In relation to the wives, ibn Qayyim said that if it wasn't forbidden for us to die in Jannah, we would die from looking at our wives.
From here, the Sheikh discussed some of the scenery and geography of Jannah. The ground of Jannah is like saffron with pebbles made of rubites and other precious stones. We will try to pick them up, but there will be too many. There are rivers of Wine, milk and honey which will always stay fresh. When you intend to take a drink from one of them, a spring will pop up for you to drink. There are trees with all forms of fruit. When we want to eat a piece of fruit, the tree will bend to bring it to us for us to bite. When we desire to eat a bird of paradise, we just think it and it will come in front of us fully cooked. We can eat as much as we want and we don't have to worry about weight and health.
On the horizon we will see the massive tree of Tuba, which gives shade to half of Jannah. The distance of travel under it is 100 years travel. It only grows in Jannah, and its bark is very silky and peels off easily in this layers like an onion.
As for our places in Jannah, the last person to enter jannah will see his kingdom, and it will be a size of 2000 years travel (in size) [my note: so imagine the size of those who are of higher degrees]
In our kingdom's we will have a tent which is made of a hollowed out pearl. This will be 600ft tall. From the outside you will be able to see the inside, and from the inside you will be able to see outside. In the tent you will meet your first wife.
The women of jannah will have petite faces, translucent type of skin so that you can see the nerves in their body, full lips, full breasted, etc...very beautiful. When they see you they will sing to you, and when you meet them it is as though you have been absent from them for a long time (as they have been waiting you...and watching you in this world). When a mujahidin goes to battle, the women of Jannah put on marriage clothes in anticipation of the Mujahidin's martyrdom. When we meet them in Jannah, they will ask us if we remember what day Allah married us to them. This day can be any point in your life; perhaps you met a point of great difficulty in your life and you had patience and firm faith.
Also in your place of Jannah you will have magnificent palaces on top of rivers. In this palace will be the rest of your wives of Jannah, and you can also have your wife from dunia as well. The female believers in jannah will be so much better in beauty than the women of Jannah. The sheikh made a statement (possibly a quote that I didn't catch the author of): Does the king think of King think of the servant when the Queen is there? Not at all.
It is possible to have children in Jannah. Pregnancy only lasts 1 hour, and you can decided what ages the children are. So you could have children that are a specific age forever so they you can always enjoy them at whatever age you like best.
At the end of your first week in Jannah, on Friday, a beautiful northern wind will blow, which makes a beautiful sound from the leaves of the Tuba tree. There will be a rain with a beautiful smell of perfume that will cleanse you. Your Buraq will come to take you to a gathering of all of the residents of Jannah at one level of Jannah. Here you can see friends, prophets, companions, etc. You will be seated in a circle on thrones of light. You can drink together and talk. After a while, and Angel will come to bring you away to an hour long face to face session with Allah.
Of all of the pleasures of paradise, nothing is better than being able to see Allah. The created tragedy is to not be able to experience this.
After we leave the gathering, we pass through the markets of Jannah which is hosted by the Angels. In it are all sorts of amazing creations of Allah. When we want something, we will realized we don't have any money, but we will be given the items on the basis of our good deeds done in this life.
The Sheikh mentioned another hadith: Whoever says: O Allah, enter me into jannah (3 times), Jannah will ask Allah to enter him into Jannah.
This is the extent of what I have in my notes. A few additional points to consider, although the description above may be wonderful, we need to know that even with these descriptions, we are absolutely incapable of imagining how great Jannah is really like. In some other narrations mentioned in other talks, 1) Allah has only given one part of his mercy in this dunia, and saved 99 for the hereafter. 2) Everyone will enter Jannah, except for the one that refuses to enter. Do not be the one that refuses to enter Jannah by the disobedience of Allah. Strive as hard as you can in this life, and have sincere intentions in all that you do (Ikhlaas, inshallah will cover some notes about that from AdbulRahman Green's talk that followed this one).
Thursday, December 27, 2012
"System detected a possible attempt to compromise security" Enter network password popup comes up on 2008R2
1) Dns registration failed (secure DDNS)
2) Group policy processing failed: Event 1053 "Could not resolve the user name"
3) LSASRV 40960 events with authentication errors to various kerberos services such as domain controllers LDAP/ SPNS, and cifs/ for the DFS namespace.
4) TerminalServices error 1067, Cannot registery TERMSRV Service Principal Name
5) When joining the domain and changing primary dns suffix "Changing the primary domain DNS name of this computer failed." "A Directory service error has occurred"
6) Klist shows no kerberos tickets
When I looked at this in netmon, all of the Kerberos transactions for TGT requests would receive a preauthentication required error from the KDC (domain controller) and it wasn't following up on that. After trying to dig around for information related to that, and any possible Kerberos settings that might impact this, I could find nothing. I looked in the registry for LSA settings and found LMCompatibilityLevel at 1. After changing this to a 2, everything started to work fine. From the Microsoft description of NT Compatibility levels, I don't see how this would impact Kerberos transactions, but apparently there may be some correlation. This fix worked for a short while, however everything broke again soon after. Later investigation found the Kerberos encryption types had been restricted to AES only, which was not compatible with the domain. After enabling RC4-HMAC, the problems went away. I have seen related issues on other machines where neither of these two should have been the problem. So perhaps there are many causes.
Tuesday, December 18, 2012
POSH What do I need to do to get a ping? (test-connection out of resources)
Error: Test-Connection : Testing connection to computer '10.0.0.1' failed: Error due to lack of resources
This is a problem as one of your attempts to handle errors becomes an error by itself. You can get around this with a few other methods. There is the standard ping.exe command which will return different error codes for status. You could use that and read the return to see if it evaluates successfully. Another way is through .NET's Net.NetworkInformation.Ping class. This can be used quickly and with few options, or if you want to control the ping you can look at Net.NetworkInformation.PingOptions.
As an example, here is an old piece of code I put together in the early Powershell v1 days.
function ping-host([string]$server) { #This function will perform a simple, small size #single packet ping of a machine and return #true/false for the result if ([string]::IsNullOrEmpty($server) ) {return $false} #ping first for reachability check $po = New-Object net.NetworkInformation.PingOptions $po.set_ttl(64) $po.set_dontfragment($true) [Byte[]] $pingbytes = (65,72,79,89) $ping = new-object Net.NetworkInformation.Ping $savedEA = $Erroractionpreference $ErrorActionPreference = "silentlycontinue" $pingres = $ping.send($server, 1000, $pingbytes, $po) if (-not $?) {return $false} $ErrorActionPreference = $savedEA if ($pingres.status -eq "Success") { return $true } else {return $false} }
This will send a very small ping packet with a 1 sec timeout, hiding any .NET error messages and returning a true or false for availability.
Thursday, November 22, 2012
LDAP AD: Finding members of a group who have it as their primary group
As an example, lets say our group was called SecondaryUsers.
In powershell we can get the object SID
$id = new-object System.Security.Principal.NTAccount(CONTOSO\SecondaryUsers)
$sid = $id.translate([system.security.principal.securityidentifier]).tostring()
$sidval = $sid.substring($sid.lastindexof('-')+1)
Now that we have our group's number, lets do an ldap search
$de = new-object directoryservices.directoryentry("LDAP://dc=contoso,dc=com")
$ds = new-object directoryservices.directorysearcher($de)
$ds.filter = "(&(objectclass=user)(|(primarygroupid=$($sidval))(memberof:=cn=SecondaryUsers,ou=MyGroups,dc=Contoso,Dc=com)))"
$ds.propertiestoload.add("samaccountname") |out-null
$users = $ds.findall()
Now we have all of the users under that group, whether they are memberof or member by PrimaryGroup.
Thursday, October 11, 2012
DES encryption and 2008R2 (does it really work?)
Java.exe "-Djava.security.krb5.kdc=MyDomainController1" "-Djava.security.krb5.conf=c:\windows\krb5.ini" "-Djava.security.krb5.realm=CONTOSO.COM" "-Djava.security.krb5.internal.crypto=DesCbcCRCEType" "sun.security.krb5.internal.tools.Kinit" someuseraccount@CONTOSO.COM UserPassword
If you look at the example above (the quotes are in there for use within powershell), the first -D option points to your KDC, which is the domain controller you want to test. The second points to a krb5.ini file (might not be required, you can search around to find the format of that if needed). The third option: Realm, is the dns name of your domain. Our fourth option is the encryption type you want to test. You can do DesCbcCRCEtype or DesCbcMd5Etype (among others), to test different types of DES encryption ticket requests. The last part of the java class paths is the Kinit class utility, and the two arguments after that are the username and password. These can be any account in the domain, and doesn't require the DES checkbox on the user account to be checked. Run this command and check output. If there are errors, it will give you further details. If DES is not supported on a domain controller, you will get an error 14 talking about encryption type no supported. Otherwise, you will get a kerberos ticket that will be stored in a file.
If you want verbose debugging details for the whole connection, you can add these two options prior to the kinit:
-Dsun.security.krb5.debug=true
-Dsun.security.krb5.krb5debug=all
If you want to test a large number of domain controllers, you can wrap this into a powershell function similar to this:
function check-dessupport {
param(
[string]$server,
[string]$realm,
[string]$user,
[string]$password
)
echo $server >>c:\temp\kerbout.txt
$res = new-object PSObject
add-member -inputobject $res NoteProperty Server $server
Java.exe "-Djava.security.krb5.kdc=$($server)" "-Djava.security.krb5.conf=c:\windows\krb5.ini" "-Djava.security.krb5.realm=$($realm)" "-Djava.security.krb5.internal.crypto=DesCbcCRCEType" "sun.security.krb5.internal.tools.Kinit" $user $password 2>>c:\temp\kerbout.txt
add-member -inputobject $res NoteProperty DesCbcCrc $?
Java.exe "-Djava.security.krb5.kdc=$($server)" "-Djava.security.krb5.conf=c:\windows\krb5.ini" "-Djava.security.krb5.realm=$($realm)" "-Djava.security.krb5.internal.crypto=DesCbcMd5EType" "sun.security.krb5.internal.tools.Kinit" $user $password 2>>c:\temp\kerbout.txt
add-member -inputobject $res NoteProperty DesCbcMd5 $?
return $res
}
This will return the server name and true/false for each time. Just note that the failure of a test can just be the server is not available or is slow to respond. This example logs the full details into c:\temp\kerbout.txt
To check the allowed encryption types that are set by policy you can look at the registry key
function check-enctypeRegEntry {
param(
[string]$server
)
$key = "Software\Microsoft\Windows\CurrentVersion\Policies\System\kerberos\parameters"
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$regkey = [Microsoft.win32.registrykey]::OpenRemoteBaseKey($type,$server)
$regkey = $regkey.opensubkey($key)
$enctypes = $regkey.getvalue("supportedencryptiontypes")
$ret = New-Object psobject
Add-Member -InputObject $ret NoteProperty Server $server
Add-Member -InputObject $ret NoteProperty EncType $enctypes
return $ret
}
And you will need to decode the numeric value from there. A decimal value of 31 is the value for all check boxes being checked except future encryption types.
For further details on dealing with DES, you can look at my previous article on the subject. If you do have everything enabled and you are at SP1 but still have DES issues, please comment on the post.
Thursday, June 28, 2012
Can you trust the man in the red underpants?
Click on the man to start exercising your mind.
Wednesday, June 27, 2012
Getting AD object metadata via powershell
#requires -version 2 param( [parameter(mandatory=$true)][alias('samaccountname','cn','username','groupname')]$name, [parameter(mandatory=$true)][ValidateSet("Group","Computer","User")] [alias('object','objecttype')]$type, [switch][alias("members","member")]$valuemeta ) #Set up connection to forest $de = New-Object directoryservices.DirectoryEntry("GC://dc=contoso,dc=com") $ds = new-object directoryservices.directorysearcher($de) #set an appropriate search filter for each type of object switch ($type) { "group" {$ds.filter = "(&(objectclass=group)(|(samaccountname=$name)(cn=$name)))" } "computer" { $ds.filter = "(&(objectclass=computer)(cn=$name))" } "user" { $ds.filter = "(&(objectclass=user)(samaccountname=$name))" } } #load up metadata attribs and search $ds.propertiestoload.add("distinguishedname") > $null $fu = $ds.findone() if ($fu -ne $null) { $de = New-Object directoryservices.DirectoryEntry("LDAP://" + $fu.properties.distinguishedname[0]) } else { Write-Error "Object not found in AD" exit 1 } $ds.searchroot = $de $ds.propertiestoload.add("msDS-ReplAttributeMetaData") > $null $ds.propertiestoload.add("msDS-ReplValueMetaData") > $Null $fu = $ds.findone() #display the requested type of data if ($valuemeta) { $xml = "<root>" + $fu.properties."msds-replvaluemetadata" + "</root>" $xml = [xml]$xml $xml.root.DS_REPL_VALUE_META_DATA | Select-Object @{name="Attribute"; expression={$_.pszAttributeName}},@{name="objectDN";expression={$_.pszObjectDN}},ftimeDeleted,ftimeCreated | Sort-Object attribute } else { $xml = "" + $fu.properties."msds-replattributemetadata" + " " $xml = [xml]$xml $xml.root.DS_REPL_ATTR_META_DATA | select-object @{name="Attribute";expression={$_.pszAttributeName}},@{name="ChangeTime";expression={$_.ftimeLastOriginatingChange}}| Sort-Object attribute } <# .DESCRIPTION Show-ADObjMeta will show the attributes and last time written on the object. .PARAMETER Name The name of the user/computer/group that you want to pull the metadata for. This should be the logon id if it is a user, the computer name for computers, and the groupname (cn or samaccountname) for groups. .PARAMETER ValueMeta Use this parameter if you want to view multivalue item metadata, like Group Member add/remove details .PARAMETER Type Specify the type of object: User, Group, Computer .EXAMPLE Show-ADObjMeta -type user -name myuser Get the metadata for attributes of myuser #>
Tuesday, June 26, 2012
Bulk adding users to a domain group based on their email address
#requires -version 2 #Bulk add by email address value param( [parameter(mandatory=$true)][ValidateScript({Test-path $_ -PathType Leaf})]$userlist, [parameter(mandatory=$true)][ValidateScript( { #This validator will check AD to see if the group exists, and it will set $script:tgtgrp to the object that #will be modified $validatesearcher = New-Object directoryservices.DirectorySearcher("GC://dc=contoso,dc=com") $validatesearcher.filter = "(&(objectclass=group)(cn=$_))" $script:tgtgrp = $validatesearcher.findone() return $tgtgrp })]$groupname ) $script:tgtgrp = [adsi]$script:tgtgrp.path $users = get-Content $userlist $de = New-Object directoryservices.DirectoryEntry("GC://dc=contoso,dc=com") $searcher = New-Object directoryservices.Directorysearcher($de) foreach ($user in $users) { try { if ($user -notmatch "@contoso.com") { throw "Entry: $user is not a valid email address" } $searcher.filter = "(&(objectclass=user)(proxyaddresses=SMTP:$user))" $userobj = $searcher.findone() if ($userobj -eq $null) { throw "Entry: $user could not be found in active directory" } try { $script:tgtgrp.properties["member"].add($userobj.properties.distinguishedname[0]) |out-null $script:tgtgrp.setinfo() } catch { throw "Error occurred when trying to add member:$($userobj.properties.distinguishedname[0]) to group" } } catch { Out-Default -InputObject $_.exception } } <# .DESCRIPTION Add-BulkUserByEmail will add users to a specified group (Used quotes around groups with spaces in them) from a text file list of user email addresses (one user per line) .PARAMETER Userlist The full path to the userlist text file (ex: c:\temp\userlist.txt) .PARAMETER Groupname The name of the group object in active directory (CN attribute value). This name must be unique in the forest, or the wrong group may be selected .EXAMPLE Add-BulkUserByEmail -userlist c:\temp\userlist.txt -groupname "My Distro List group" #>
Monday, June 4, 2012
Trinity - summed up in one verse
I have seen a lot of attempts to wrap the idea of trinity (God being 3 in 1), by projecting this philosophy on to various verses in ways that make the verse mean other than what it obviously means. In other cases, there were fabricated verses inserted into the bible. And in more we have people attempting to explain away glaring contradictions by saying Jesus didn't know he was God, or was only human at that specific time...basically grasping at straws with no knowledge of the incident in question. I thought I would sum up the trinity in one verse using basic logic. The verse:
Mark 10:18 (Comparitive translations)
"Why do you call me good?" Jesus answered. "No one is good--except God alone."
This is in response to a man just calling Jesus "Good teacher" and asking for guidance on how to get eternal life. Since Jesus was a teacher of goodness and called people to the truth, this would be an appropriate title to address him with. But Jesus responds that only God is good. Lets look at this from the perspective of Jesus and God being part of a trinity.
In Trinity: Jesus = God
In Logic: Jesus says only God is good, thus stating that he is not, by his rejection of the man's
assertion Jesus = Good, he implies Jesus != Good
If Jesus = God, Jesus would be the same entity and (Jesus = Good) must also be true.
Since he is rejecting this statement, then this must be true:
Jesus != God
Additionally, in the verse, the word used is "God", not "The Father". So there is no means that anyone could try to say that they are still the same essence, with one being better than the other in some way.
Besides the logical argument, look how Jesus reacts to the statement. He could have ignored it, or assumed it was a simple compliment, but he instead immediately redirected the focus to the One that is worthy of all praise...OUR LORD. Jesus stated that the most important commandment is the first commandment; the oneness of God. This is a perfect demonstation of giving God what is due to Him, as Jesus said, I of myself can do nothing.
There are many obvious verses that point to this truth. Even verses used to "prove" the trinity, do more to disprove it than they do to support it. I hope the Christians of the world contemplate deeply about the nature of their faith and the source of their book. Look deep for truth. Ask yourself why none of the messengers talked about trinity or God being multiple parts. When asked what is the most important of commandments, Jesus stated in Mark 12:29 that is the first: "Hear, O Israel: The Lord our God, the Lord is one." Jesus points out that he is an example to follow, yet none follow his ways of doing things. For the sincere of faith, and the one that truly wants success in thereafter, pray as Jesus prayed (Matthew 26:39) and ask our Lord (the father) for guidance to see truth and to know the way to return to him with success. It would be a tragedy if the good works you do are in vain because you haven't applied the first commandment.
Start looking for answers with sincerity.
A good place to start, The true message of Jesus
For some more points to consider, please view some points from my next post.
Thursday, April 26, 2012
Decoding AD ACL's (Powershell)
ActiveDirectoryRights : CreateChild, DeleteChild
InheritanceType : None
ObjectType : bf967aa8-0de6-11d0-a285-00aa003049e2
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : ObjectAceTypePresent
AccessControlType : Allow
IdentityReference : S-1-5-32-550
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
Here, you can see many of the enumerations are decoded into text, but we have guid's and SID's that may show up without translation. With BSonPosh, there is a function for converting SID's already, though in this case I'm modifying it to handle SID's that do not translate with that code. Combining that with another helper function to decode the GUID's to the ldap display attribute listed in the schema, you can get a result that is more readable like this:
Get-ADACL -distinguishedname "dc=contoso,dc=com" | convert-adacl
ActiveDirectoryRights : ReadProperty, WriteProperty, Delete
InheritanceType : Descendents
ObjectType : msRTCSIP-UserPolicies
InheritedObjectType : user
ObjectFlags : ObjectAceTypePresent, InheritedObjectAceTypePresent
AccessControlType : Allow
IdentityReference : CONTOSO\RTCDomainUserAdmins
IsInherited : False
InheritanceFlags : ContainerInherit
PropagationFlags : InheritOnly
Below is the code. One function was changed (ConvertTO-Name). The rest is added to BSActiveDirectory.psm1. It is important to note, that this conversion function creates its own custom PSobject, so it is not longer an ACL that you can play with and try to write back. This was more designed for auditing purposes.
#region Convert-ADACL function Convert-ADACL { <# .Synopsis Translates the AD Object ACL to a more readable format by converting SID and GUID values to text .Description Translates the AD Object ACL to a more readable format by converting SID and GUID values to tex .Parameter ACL ACL Object to Apply .OUTPUTS Object #> [cmdletbinding()] Param( [Parameter(ValueFromPipeline=$true)] [System.DirectoryServices.ActiveDirectoryAccessRule]$ACL ) Begin { $results = @() } process { if ($_.ActiveDirectoryRights -eq "ExtendedRight") { $myresult = New-Object PSobject -Property @{ ActiveDirectoryRights = $_.ActiveDirectoryRights InheritanceType = $_.InheritanceType ObjectType = Convert-GUIDToName -guid $_.objecttype -extended
InheritedObjectType = Convert-GUIDToName -guid $_.inheritedobjecttype ObjectFlags = $_.ObjectFlags AccessControlType = $_.accesscontroltype IdentityReference = ConvertTo-Name -sid $_.identityReference IsInherited = $_.isinherited InheritanceFlags = $_.InheritanceFlags PropagationFlags = $_.PropagationFlags } } else { $myresult = New-Object PSobject -Property @{ ActiveDirectoryRights = $_.ActiveDirectoryRights InheritanceType = $_.InheritanceType ObjectType = Convert-GUIDToName -guid $_.objecttype InheritedObjectType = Convert-GUIDToName -guid $_.inheritedobjecttype
ObjectFlags = $_.ObjectFlags AccessControlType = $_.accesscontroltype IdentityReference = ConvertTo-Name -sid $_.identityReference IsInherited = $_.isinherited InheritanceFlags = $_.InheritanceFlags PropagationFlags = $_.PropagationFlags } } $results += $Myresult } end { $results |Select-Object ActiveDirectoryRights,InheritanceType,ObjectType,InheritedObjectType,ObjectFlags,` AccessControlType,IdentityReference,IsInherited,InheritanceFlags,PropagationFlags } } #endregion #region ConvertTo-Name function ConvertTo-Name { param($sid) Write-Verbose $sid try { $ID = New-Object System.Security.Principal.SecurityIdentifier($sid) $User = $ID.Translate( [System.Security.Principal.NTAccount]) $User.Value } catch { switch($sid) { #Reference http://support.microsoft.com/kb/243330 "S-1-0" { "Null Authority" } "S-1-0-0" { "Nobody" } "S-1-1" {"World Authority" } "S-1-1-0" { "Everyone" } "S-1-2" { "Local Authority" } "S-1-2-0" { "Local" } "S-1-2-1" { "Console Logon" } "S-1-3" { "Creator Authority" } "S-1-3-0" { "Creator Owner" } "S-1-3-1" { "Creator Group" } "S-1-3-4" { "Owner Rights" } "S-1-5-80-0" {"All Services" } "S-1-4" { "Non Unique Authority" } "S-1-5" { "NT Authority" } "S-1-5-1" { "Dialup" } "S-1-5-2" { "Network" } "S-1-5-3" { "Batch" } "S-1-5-4" { "Interactive" } "S-1-5-6" { "Service" } "S-1-5-7" { "Anonymous" } "S-1-5-9" { "Enterprise Domain Controllers"} "S-1-5-10" { "Self" } "S-1-5-11" { "Authenticated Users" } "S-1-5-12" { "Restricted Code" } "S-1-5-13" { "Terminal Server Users" } "S-1-5-14" { "Remote Interactive Logon" } "S-1-5-15" { "This Organization" } "S-1-5-17" { "This Organization" } "S-1-5-18" { "Local System" } "S-1-5-19" { "NT Authority Local Service" } "S-1-5-20" { "NT Authority Network Service" } "S-1-5-32-544" { "Administrators" } "S-1-5-32-545" { "Users"} "S-1-5-32-546" { "Guests" } "S-1-5-32-547" { "Power Users" } "S-1-5-32-548" { "Account Operators" } "S-1-5-32-549" { "Server Operators" } "S-1-5-32-550" { "Print Operators" } "S-1-5-32-551" { "Backup Operators" } "S-1-5-32-552" { "Replicators" } "S-1-5-32-554" { "Pre-Windows 2000 Compatibility Access"} "S-1-5-32-555" { "Remote Desktop Users"} "S-1-5-32-556" { "Network Configuration Operators"} "S-1-5-32-557" { "Incoming forest trust builders"} "S-1-5-32-558" { "Performance Monitor Users"} "S-1-5-32-559" { "Performance Log Users" } "S-1-5-32-560" { "Windows Authorization Access Group"} "S-1-5-32-561" { "Terminal Server License Servers"} "S-1-5-32-561" { "Distributed COM Users"} "S-1-5-32-569" { "Cryptographic Operators" } "S-1-5-32-573" { "Event Log Readers" } "S-1-5-32-574" { "Certificate Services DCOM Access" } "S-1-5-32-575" { "RDS Remote Access Servers" } "S-1-5-32-576" { "RDS Endpoint Servers" } "S-1-5-32-577" { "RDS Management Servers" } "S-1-5-32-575" { "Hyper-V Administrators" } "S-1-5-32-579" { "Access Control Assistance Operators" } "S-1-5-32-580" { "Remote Management Users" } default {$sid} } } } #endregion #region Convert-GUIDToName #helper module to convert schema GUID's to readable names function Convert-GUIDToName { param( [parameter(mandatory=$true)][string]$guid, [switch]$extended ) $guidval = [Guid]$guid $bytearr = $guidval.tobytearray() $bytestr = "" foreach ($byte in $bytearr) { $str = "\" + "{0:x}" -f $byte $bytestr += $str } if ($extended) { #for extended rights, we can check in the configuration container $de = new-object directoryservices.directoryentry("LDAP://" + ([adsi]"LDAP://rootdse").psbase.properties.configurationnamingcontext) $ds = new-object directoryservices.directorysearcher($de) $ds.propertiestoload.add("displayname")|Out-Null $ds.filter = "(rightsguid=$guid)" $result = $ds.findone() } else { #Search schema for possible matches for this GUID $de = new-object directoryservices.directoryentry("LDAP://" + ([adsi]"LDAP://rootdse").psbase.properties.schemanamingcontext) $ds = new-object directoryservices.directorysearcher($de) $ds.filter = "(|(schemaidguid=$bytestr)(attributesecurityguid=$bytestr))" $ds.propertiestoload.add("ldapdisplayname")|Out-Null $result = $ds.findone() } if ($result -eq $null) { $guid } else { if ($extended) { $result.properties.displayname } else { $result.properties.ldapdisplayname } } } #endregion
Update: 1/29/2013
Just an additional note. Since you need distinguishednames for the commandlets, this can be a pain at times. If you like to use dsquery for quick and short results you can pipe these in, however you need to deal with the quotations that are put around the dsquery output. Example:
dsquery group -name Mygroup | foreach {$_.replace("`"","")} | get-adacl | where {$_.isinhertied -eq $false} |convert-adacl
Update: Sept 2020
It looks like all the links to the BSOnPosh module are broken now. Below is the functions that were referenced from there.
function Get-ADACL { <# .Synopsis Gets ACL object or SDDL for AD Object .Description Gets ACL object or SDDL for AD Object .Parameter DistinguishedName DistinguishedName of the Object to Get the ACL from .Parameter SDDL [switch] If passed it will return the SDDL string .Example Get ACL for ‘cn=users,dc=corp,dc=lab’ Get-ADACL ‘cn=users,dc=corp,dc=lab’ Get SDDL for ‘cn=users,dc=corp,dc=lab’ Get-ADACL ‘cn=users,dc=corp,dc=lab’ -sddl .Outputs Object .Link N/A .Notes NAME: Get-ADACL AUTHOR: YetiCentral\bshell Website: www.bsonposh.com #Requires -Version 2.0 #> [Cmdletbinding()] Param( [Alias('dn')] [ValidatePattern('^((CN|OU)=.*)*(DC=.*)*$')] [Parameter(ValueFromPipeline=$true,Mandatory=$True)] [string]$DistinguishedName, [Parameter()] [switch]$SDDL ) Write-Verbose " + Processing Object [$DistinguishedName]" $DE = [ADSI]"LDAP://$DistinguishedName" Write-Verbose " - Getting ACL" $acl = $DE.psbase.ObjectSecurity if($SDDL) { Write-Verbose " - Returning SDDL" $acl.GetSecurityDescriptorSddlForm([System.Security.AccessControl.AccessControlSections]::All) } else { Write-Verbose " - Returning ACL Object [System.DirectoryServices.ActiveDirectoryAccessRule]" $acl.GetAccessRules($true,$true,[System.Security.Principal.SecurityIdentifier]) } }
Thursday, April 19, 2012
Powershell overlapping pipeline problem
function get-physicalphysical {
param( [parameter(position=0)][string]$nicGUID )
$vals = Get-ChildItem hklm:"\System\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}" |
get-itemproperty -name $_.name | where {$_.netcfginstanceid -match $nicGuid}
if ($vals.characteristics -eq 0x84) { return $true } else { return $false }
}
$nics = Get-WmiObject -Class Win32_NetworkAdapter -Filter "PhysicalAdapter = True" |
where {get-physicalphysical $($_.guid)}
So we have GWMI for network adapters piped to a function called get-physicalphysical. The guid of the WMI network adapter result is searched in the registry for lower level details that are not available via WMI. The error we get is something like this (repeating many times and for different adapter names)
Get-ItemProperty : Property Intel(R) 82567LM Gigabit Network Connection does not exist at path HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0000.
At line:11 char:25
+ get-itemproperty <<<< -name $_.name | where {$_.netcfginstanceid -ma
tch $nicGuid}
+ CategoryInfo : InvalidArgument: (Intel(R) 82567L...work Connect
ion:String) [Get-ItemProperty], PSArgumentException
+ FullyQualifiedErrorId : System.Management.Automation.PSArgumentException
,Microsoft.PowerShell.Commands.GetItemPropertyCommand
In this case, the WMI results have a property called Name, and the entries in the registry that we were looking at also have a value for Name. What we want is the name of the registry key that contains the configurations for the adapter. But with the use of two pipelines, it appears that the $_ referenced in the pipeline within the function is accessing the pipeline $_ from outside of the function. I'm not expert in low level powershell details and how the pipeline works, but after playing around a bit with trying to scope the $_ variable, and eventually reading the about_functions help, I found that you can scope a function. By scoping the function and the $_ variable within it (using the same scope), I was able to separate the two pipelines and accomplish what I was hoping for. You can see the full code at the entry script.
Friday, March 23, 2012
AD Powershell module and managing multiple domains
Get-Acl : A referral was returned from the server
Since AD: is a PSDrive, there is no reason you can't add some more for other domains. Lets say you have two domains, contoso.com and child.contoso.com
New-PSDrive -Name "Child" -Root "" -PsProvider ActiveDirectory -server (Get-ADDomainController -domain child.contoso.com -discover -writable).name
This will create a PSDrive called Child:, which will reference this domain. So to work with get-acl you can reference child:"objectdn" to get the acl. For other commandlets, set-location child: and try using these to access objects in it.
If you wanted to auto-create a drive for every domain in your forest you could do this easily (though a bit slowly). PSDrive names are limited in that they cannot contain '.', so in this example I'm just stripping a domain's first portion of its name out:
(get-adforest).domains|foreach {$temp = $_.substring(0,$_.indexof('.')); New-PSDrive -Name $temp -Root "" -PsProvider ActiveDirectory -server (Get-AD
DomainController -domain $_ -discover -writable).name}
Update:
After trying to work with the Microsoft AD powershell module for this, and having a lot of problems in a mixed 2008/2003 multidomain environment, I ran into the BSonPosh module. This has a much simpler way of reading and writing ACL's in AD which looks like it will run very easily in a multidomain environement, or non-2008 AD domain. I have a extension to the module to Decode AD ACL.Wednesday, March 21, 2012
Checking NIC for collisions (speed/duplex mismatch) Windows Powershell
Results in PSObject array of all NIC's
Computername NicName LinkSpeed Collisions ------------ ------- --------- ---------- MyComputer Intel(R) PRO/100... 100 0
function get-NicError ([string]$server) { #This function uses WMI queries against the target machine to get link speed information and #check for any recorded network collissions. It combines the two queries to print out collisions #per adapter with link speed. if ([string]::IsNullOrEmpty($server)) { write-host -foregroundcolor "yellow" "Usage: get-NicError servername" write-host -foregroundcolor "yellow" " Get speed and collision details for network adapters" return } $result = @() $a = gwmi -namespace root\wmi -class msndis_ethernetmoretransmitcollisions -computername $server |select-object instancename,ndisethernetmoretransmitcollisions $b = gwmi -namespace root\wmi -class msndis_linkspeed -computername $server | select-object instancename,ndislinkspeed if (($a -eq $null) -or ($b -eq $null)) { write-error "WMI connection error" return } foreach ($link in $b) { $link.ndislinkspeed = $link.ndislinkspeed / 10000 } foreach ($item in $a) { foreach ($seconditem in $b) { if ($item.instancename -eq $seconditem.instancename) { $myres = New-Object psobject Add-Member -InputObject $myres NoteProperty Computername $server Add-Member -InputObject $myres Noteproperty NicName $item.instancename Add-Member -InputObject $myres Noteproperty LinkSpeed $seconditem.ndislinkspeed Add-Member -InputObject $myres Noteproperty Collisions $item.ndisethernetmoretransmitcollisions $result += $myres } } } return $result }
Thursday, February 23, 2012
Crazy uptime (windows 2000 domain controller)
\\SRVNAMECHANGED has been up for: 2111 day(s), 10 hour(s), 31 minute(s), 52 second(s)
Anyone got a datacenter and server that stable? This is a Dell PE2650 with windows 2000, which also has 0 hardware problems.
Tuesday, February 21, 2012
Converting guid to escaped bytes for LDAP lookups (powershell, AD ACL)
ActiveDirectoryRights : CreateChild, DeleteChild
InheritanceType : None
ObjectType : bf967aa8-0de6-11d0-a285-00aa003049e2
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : ObjectAceTypePresent
AccessControlType : Allow
IdentityReference : S-1-5-32-550
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
Given that the ObjectType and occsionally the InheritedObjectType are guid's, it may be difficult to determine what this entry is referring to. You can do an ldap lookup into the schema partition to find what object or attribute this guid is referring to, however the ldap filter for the search needs the guid in binary. .Net comes to the rescue for easy conversion to binary, but this is not sufficient for an ldap search, as it returns a byte array.
You can create a GUID object in powershell by casting $myguid = [guid]"bf967aa8-0de6-11d0-a285-00aa003049e2"
In this object, there is a byte conversion method tobytearray().
For ldap searches, we need the byte array escaped with forward slashes on each byte. To do this you can run the guid through this simple function
function guid-toescapedbyte($guid) {
$bytearr = $guid.tobytearray()
$bytestr = ""
foreach ($byte in $bytearr) {
$str = "\" + "{0:x}" -f $byte
$bytestr += $str
}
return $bytestr
}
In our example we will get this:
guid-toescapedbyte([guid]"bf967aa8-0de6-11d0-a285-00aa003049e2")
\a8\7a\96\bf\e6\d\d0\11\a2\85\0\aa\0\30\49\e2
We can add this to a filter like this:
$de = new-object directoryservices.directoryentry("LDAP://cn=schema,cn=configuration,dc=contoso,dc=com")
$ds = new-object directoryservices.directorysearcher($de)
$bytestr = guid-toescapedbyte [guid]"bf967aa8-0de6-11d0-a285-00aa003049e2"
$ds.filter = "(|(schemaidguid=$bytestr)(attributesecurityguid=$bytestr))"
$ds.findone().properties
Name Value
---- -----
systemmustcontain {versionNumber, uNCName, shortServerName, ser...
admindisplayname {Print-Queue}
name {Print-Queue}
objectguid {184 69 64 30 219 21 163 78 168 107 59 106 18...
systemonly {False}
whencreated {10/21/1630 4:21:11 PM}
defaultobjectcategory {CN=Print-Queue,CN=Schema,CN=Configuration,DC...
systemflags {16}
ldapdisplayname {printQueue}
usnchanged {4748}
objectcategory {CN=Class-Schema,CN=Schema,CN=Configuration,D...
systemposssuperiors {organizationalUnit, domainDNS, container, co...
showinadvancedviewonly {True}
defaultsecuritydescriptor {D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RP...
instancetype {4}
distinguishedname {CN=Print-Queue,CN=Schema,CN=Configuration,DC...
cn {Print-Queue}
dscorepropagationdata {1/1/1601 12:00:00 AM}
objectclass {top, classSchema}
defaulthidingvalue {False}
usncreated {4748}
rdnattid {cn}
objectclasscategory {1}
systemmaycontain {priority, printStatus, printStartTime, print...
schemaidguid {168 122 150 191 230 13 208 17 162 133 0 170 ...
subclassof {connectionPoint}
whenchanged {6/11/2010 5:23:32 PM}
governsid {1.2.840.113556.1.5.23}
admindescription {Print-Queue}
adspath {LDAP://CN=Print-Queue,CN=Schema,CN=Configura...
And we can see from our results that our ACL is related to print queue child objects. If we translate the SID, we will see this is the print operators builtin group.
Thursday, February 16, 2012
Wednesday, February 1, 2012
Dell components check for updates via powershell (remote machine SUU)
Component : FlashBIOS Updates
path : PE2850_BIOS_WIN_A07.EXE
vendorVersion : A07
currentversion : A05
releaseDate : May 23, 2008
Criticality : Optional
AtCurrent : False
Component : Embedded Server Management
path : BMC_FRMW_WIN_R223079.EXE
vendorVersion : 1.83
currentversion : 1.52
releaseDate : June 30, 2009
Criticality : Optional
AtCurrent : False
for all firmware, bios, and drivers (probably OMSA too). The AtCurrent value is a true/false test to show if you are at the current level (current to your version of SUU that you are using). The script takes a server name and path (to your catalog.xml file in the suu\repository folder), and remotely checks the machine. This works for windows machines only, since it uses WMI. I'm sure some method of scripting using omreport data could be used to due similiar work for Linux. Some ideas for using this information for updating, take the file name returned in each component, copy the file from the repository to the remote machine and run the installs with the silent run switch.
#Requires -version 2 #Author: Nathan Linley #Script: Computer-DellUpdates #Date: 2/9/2012 param( [parameter(mandatory=$true)][ValidateScript({test-path $_ -pathtype 'leaf'})][string]$catalogpath, [parameter(mandatory=$true,ValueFromPipeline=$true)][string]$server ) function changedatacase([string]$str) { #we need to change things like this: subDeviceID="1f17" to subDeviceID="1F17" #without changing case of the portion before the = if ($str -match "`=`"") { $myparts = $str.split("=") $result = $myparts[0] + "=" + $myparts[1].toupper() return $result } else { return $str} } $catalog = [xml](get-Content $catalogpath) $oscodeid = &{ $caption = (Get-WmiObject win32_operatingsystem -ComputerName $server).caption if ($caption -match "2003") { if ($caption -match "x64") { "WX64E" } else { "WNET2"} } elseif ($caption -match "2008 R2") { "W8R2" } elseif ($caption -match "2008" ) { if ($caption -match "x64") { "WSSP2" } else { "LHS86" } } } write-debug $oscodeid $systemID = (Get-WmiObject -Namespace "root\cimv2\dell" -query "Select Systemid from Dell_CMInventory" -ComputerName $server).systemid $model = (Get-WmiObject -Namespace "root\cimv2\dell" -query "select Model from Dell_chassis" -ComputerName $server).Model $model = $model.replace("PowerEdge","PE").replace("PowerVault","PV").split(" ") #model[0] = Brand Prefix #model[1] = Model # $devices = Get-WmiObject -Namespace "root\cimv2\dell" -Class dell_cmdeviceapplication -ComputerName $server foreach ($dev in $devices) { $xpathstr = $parts = $version = "" if ($dev.Dependent -match "(version=`")([A-Z\d.-]+)`"") { $version = $matches[2] } else { $version = "unknown" } $parts = $dev.Antecedent.split(",") for ($i = 2; $i -lt 6; $i++) { $parts[$i] = &changedatacase $parts[$i] } $depparts = $dev.dependent.split(",") $componentType = $depparts[0].substring($depparts[0].indexof('"')) Write-Debug $parts[1] if ($dev.Antecedent -match 'componentID=""') { $xpathstr = "//SoftwareComponent[@packageType='LWXP']/SupportedDevices/Device/PCIInfo" if ($componentType -match "DRVR") { $xpathstr += "[@" + $parts[2] + " and @" + $parts[3] + "]/../../.." $xpathstr += "/SupportedOperatingSystems/OperatingSystem[@osVendor=`'Microsoft`' and @osCode=`'" + $osCodeID + "`']/../.." } else { $xpathstr += "[@" + $parts[2] + " and @" + $parts[3] + " and @" + $parts[4] + " and @" + $parts[5] + "]/../../.." #$xpathstr += "/SupportedSystems/Brand[@prefix=`'" + $model[0] + "`']/Model[@systemID=`'" + $systemID + "`']/../../.." $xpathstr += "/ComponentType[@value='FRMW']/.." } $xpathstr += "/ComponentType[@value=" + $componentType + "]/.." } else { $xpathstr = "//SoftwareComponent[@packageType='LWXP']/SupportedDevices/Device[@" $xpathstr += $parts[0].substring($parts[0].indexof("componentID")) $xpathstr += "]/../../SupportedSystems/Brand[@prefix=`'" + $model[0] + "`']/Model[@systemID=`'" $xpathstr += $systemID + "`']/../../.." } Write-Debug $xpathstr $result = Select-Xml $catalog -XPath $xpathstr |Select-Object -ExpandProperty Node $result |Select-Object @{Name="Component";Expression = {$_.category.display."#cdata-section"}},path,vendorversion,@{Name="currentversion"; Expression = {$version}},releasedate,@{Name="Criticality"; Expression={($_.Criticality.display."#cdata-section").substring(0,$_.Criticality.display."#cdata-section".indexof("-"))}},@{Name="AtCurrent";Expression = {$_.vendorVersion -le $version}} }
Tuesday, January 31, 2012
Powershell XML XPATH search example (Dell SUU)
Here's an example of getting started with this:
$catalog = [xml](get-content c:\temp\suu\repository\catalog.xml)
$devices = Get-wmiobject -namespace "root\cimv2\dell" -class Dell_cmdevice
$mydevice = $devices[0]
$xpathstr = "//SoftwareComponent[@packageType='LWXP']/SupportedDevices/Device/PCIInfo"
$xpathstr += "[@deviceID=`'" + $mydevice.deviceID + "`' and @vendorID=`'" + $mydevice.vendorID +"`' and @subDeviceID=`'" + $mydevice.subDeviceID + "`' and @subVendorID=`'" + $mydevice.subvendorID + "`']/../../.."
select-xml $catalog -xpath $xpathstr |select-object -expandproperty Node
This will give you something like this:
schemaVersion : 1.0
packageID : R222914
releaseID : R222914
hashMD5 : 6944D638979E5CE651234D216AFDC3C7
path : RAC_FRMW_WIN_R222914.EXE
dateTime : 2009-06-30T14:33:14-05:00
releaseDate : June 30, 2009
vendorVersion : 1.75
dellVersion : A01
packageType : LWXP
Name : Name
ComponentType : ComponentType
Description : Description
LUCategory : LUCategory
Category : Category
SupportedDevices : SupportedDevices
ImportantInfo : ImportantInfo
Criticality : Criticality
As you can see, the device that is being check is a RAC card. This is the latest update package for it. You can use other classes in the Dell WMI namespace to pull the current version details of your devices to compare it to what is available in the SUU repository. This part its a bit hackish though as you need to look at Dell_CMDeviceApplication and pull data out of the middle of strings, or combine Dell_CMDeviceApplication with Dell_CMApplication class results to get an easier version number. The Dell_CMDeviceApplication class seems to just bridge between two different classes giving data like this:
Antecedent : //Server/root/cimv2/dell:Dell_CMDevice.componentID="
",name="Dell Remote Access Controller 4/I",vendorID="1028",d
eviceID="0012",subDeviceID="0012",subVendorID="1028",bus="",
device="",function=""
Dependent : //Server/root/cimv2/dell:Dell_CMApplication.componen
tType="FRMW",subComponentID="",version="1.35",name="Dell Rem
ote Access Controller 4/I Firmware",deviceKey=":Dell Remote
Access Controller 4/I:1028:0012:0012:1028:::"
In the future, I will pull this together a bit more and try to provide a working SUU check for all devices on a Dell system along with update options. Update: Solution sample
Thursday, January 26, 2012
Finding a domaincontroller in powershell (without add ons and AD module)
(get-addomaincontroller -mimumdirectoryserviceversion Windows2008 -discover -avoidself -nextclosestsite).hostname
I considered .NET's active directory collection, but the methods to find domain controllers with that, have really limited locator options. I didn't see any method for finding only 2008 domain controllers and higher, so I fell back to command line tools.
This can be done with the nltest.exe:
(nltest /dsgetdc:yourdomain.com /DS_6 /avoidself)[0].substring(17)
It is a bit messy, and hackish with the substring, but it works just fine as long as you have a 2008 dc in that domain. Otherwise, it returns a single string instead of an array, and you can see the "Cannot index into a null array" exception.
PSRemoting out of memory (NTDSUTIL)
ntdsutil ifm "activate instance ntds" ifm "create sysvol full d:\ifm"
on the remote system. This can be done through invoke-command with this command as the scriptblock, however it was failing with a JET out of memory exception.
Target Database: d:\ifm\Active Directory\ntds.dit
Defragmentation Status (% complete)
0 10 20 30 40 50 60 70 80 90 100
|----|----|----|----|----|----|----|----|----|----|
........Operation terminated with error -1011( JET_errOutOfMemory, Out of Memory ).
error 0x800720d9(A database error has occurred.)
Searching around a bit, led to finding the WSMAN limitations of per shell memory. Configured as:
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 1024
Configuring this on the local machine (the non-domain controller) didn't help. Trying to configure it on the remote machine with invoke-command gives access denied. To work on the remote machine, I found this helpful article which shows the Connect-wsman commandlet connecting to a remote machine:
connect-wsman remotemachine
set-item wsman:\remotemachine\Shell\MaxMemoryPerShellMB 1024
This setting chance was enough to complete the IFM collection on the remote machine.
Wednesday, January 25, 2012
For NYMB christian visitors
For further details, check out this recent post.