Display domain information using Powershell - powershell

How can I display the domain, name and site (and nothing else) of all domain controllers using a single PowerShell command?
I've tried Get-ADDomainController cmdlet, but I only seem to get the local domaincontroller and not the information of my second server.

$getdomain = [System.Directoryservices.Activedirectory.Domain]::GetCurrentDomain()
$getdomain | ForEach-Object {$_.DomainControllers} |
ForEach-Object {
$hEntry= [System.Net.Dns]::GetHostByName($_.Name)
New-Object -TypeName PSObject -Property #{
Forest = $_.Forest
Name = $_.Name
IPAddress = $hEntry.AddressList[0].IPAddressToString
}
}
Source: https://gallery.technet.microsoft.com/scriptcenter/Get-List-of-Domain-4c993070

Related

Change a Windows product key remotely with PowerShell

I'm trying to install/activate a MAK key on remote servers. All of them have RemotePS enabled and firewall exception rules in place.
$Results = Invoke-Command -ComputerName Server1 {
$Props = #{ComputerName = $env:ComputerName}
slmgr.vbs /ipk "12345-12345-12345-12345-12345"
$LicStatus = slmgr.vbs /dlv
$Props.Add('LicenseStatus',$LicStatus)
New-Object -TypeName PSObject -Property $Props
}
$Results | Select-Object ComputerName,LicenseStatus
The above does install the MAK key but I don't get any confirmation of this process which is why I've tried adding in the license check option (/dlv) but get nothing returned in the LicenseStatus field. I'm assuming this is because it returns a multi-value maybe!?
Ultimately I'm just trying to get confirmation that the key was installed. There are articles out there about performing this using RemotePS but they all say a notification message is returned for each computer which isn't the case in my experience: https://4sysops.com/archives/change-a-product-key-remotely-with-powershell/
Any ideas how I can check this?
I would call the slmgr.vbs script using Cscript.exe in order to get the results as string array. Otherwise the system will default to using Wscript.exe which is designed to output everything in a messagebox.
Unfortunately, all output of slmgr is localized, so using a regex or something on the LicenseStatus is a no go (on a Dutch NL machine it reads 'Licentiestatus')
What you can do is using switch /dli, because that returns a string array where the last (not empty) value has the status.
Try
$Results = Invoke-Command -ComputerName Server1 {
# install MAK key
$null = cscript.exe "$env:SystemRoot\System32\slmgr.vbs" /ipk "12345-12345-12345-12345-12345"
# test LicenseStatus
$LicStatus = (((cscript.exe "$env:SystemRoot\System32\slmgr.vbs" /dli) |
Where-Object { $_ -match '\S' })[-1] -split ':', 2)[1].Trim()
# return an object
[PsCustomObject]#{
ComputerName = $env:COMPUTERNAME
LicenseStatus = $LicStatus
}
}
$Results

Exchange Attribute msExchRecipientTypeDetails

I'm trying to get the value of msExchRecipientTypeDetails for a user using PowerShell and ADSI but I'm getting System.__ComObject.
I'm not able to move forward on getting the exact string.
I'm using below PowerShell command
$ADUsr = [ADSI]"LDAP://CN=User Name,OU=OrgUnit,DC=dc,DC=dc,DC=dc"
$ADUsr.msExchRecipientTypeDetails
And result are show below
PS C:\Windows\system32> $ADUsr.msExchRecipientTypeDetails
System.__ComObject
How Can I get the exact string value? I'm expecting to get "2147483648" for UserMailbox
Any help is appreciated!
I am able to see the value of this property if i use a directory searcher to retrieve the user object:
$Searcher = New-Object DirectoryServices.DirectorySearcher
$Searcher.Filter = "(&(objectCategory=person)(sAMAccountName=testuser))"
$Searcher.SearchRoot = 'LDAP://DC=test,DC=domain,DC=au'
$Object = $Searcher.FindOne()
$Object .Properties.msexchrecipienttypedetails
Or you can simply use the powershell cmdlet:
Get-aduser testuser -Properties msExchRecipientTypeDetails
Unfortunately, I can't use PS for AD.
Tailored this to work how I wanted. I already have the user DN queried at the top of the script for another purpose
$UserDN = dsquery user forestroot -samid "USERNAME"
The rest to check for other attributes
$Searcher = New-Object DirectoryServices.DirectorySearcher
$LDAPPath = "LDAP://"+$UserDN
$Searcher.SearchRoot = $LDAPPath
$Object = $Searcher.FindOne()
$DisUsr = $Object.Properties.useraccountcontrol | Select -First 1
$SGMembership = $Object.Properties.memberof
$RecipientTypeDetails = $Object.Properties.msexchrecipienttypedetails | Select -First 1
$RemoteRecipientType = $Object.Properties.msexchremoterecipienttype | Select -First 1

Get the users who are having server access for my server

We need to extract a report every month for our servers which should report who all are having the server admin access .This will help us remove the people for whom access is no more needed. Its taking lot of time to extract manually and I read on blogs that PowerShell is used to automate such kind of administration jobs.
Other details:
Server - Win 2008 R2
Powershell 1.0
Could any one help me how to I extract this report?
Here's a quick way to enumerate the list of administrators for a server.
$group = [ADSI]"WinNT://./Administrators"
#($group.Invoke("Members")) | foreach {
$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
}
You can then use an email cmdlet to send it or however you want to send it back to you.
See: http://blogs.technet.com/b/heyscriptingguy/archive/2013/10/27/the-admin-s-first-steps-local-group-membership.aspx
There's no need for ADSI and PSRemoting. Example:
$cComputerNames = #("computer1", "computer2")
$cRows = #()
foreach ($sComputerName in $cComputerNames) {
$cAdminAccounts = Get-WmiObject -ComputerName $sComputerName `
-Class "Win32_GroupUser" `
| Where-Object {
($_.GroupComponent -split '"')[3] -eq "Administrators"
}
foreach ($cAdminAccount in $cAdminAccounts) {
$oRow = New-Object -TypeName PSObject -Property #{
"ComputerName" = $sComputerName
"AccountDomain" = ($cAdminAccount.PartComponent -split '"')[1]
"AccountName" = ($cAdminAccount.PartComponent -split '"')[3]
}
$cRows += $oRow
}
}
$cRows | Export-Csv -Path "admin-accounts.csv" -NoTypeInformation
You can use an associators of ... query to get more detailed info about accounts. See this blog post.

How to get server information from VMware

I have access to the VMWare GUI and I can easily export all the columns such as UPtime, IPAddress, Notes, DNS, GuestOs, State, Name and so on.
I want to right a script that can automatically get this information daily. So gar I was only able to get the server name, power state and VMhost. for some reason VMware is making it so hard to extract that information. I used the script below and I thought by adding the columns I mentioned above to this script, I should be able to retireve the data I need. But it doesn't work that way. Can someone please tell me how I can get this information?
Thanks,
Add-PSSnapin vmware.vimautomation.core
Connect-VIServer SERVERNAME
Get-VM|Select Name, VMHost, Id, PowerState
Exit 0
After digging into the system and many hours of research I found the solution. I just wish VMWare would make it easier to retrieve data or at least improve the manual.
The following code creates two files; one with the server information and another one with Uptime information.
Get-VM | select name,VMHost, #{ Name = "IP Addresses"; Expression = { $_.Guest.IPAddress }}, #{ Name = "PowerState"; Expression = { $_.Guest.State }} , #{ Name = "GuestOS"; Expression = { $_.Guest }}, Notes | Export-Csv -Path "HQstat.csv"
Get-Stat -Entity * -Stat sys.uptime.latest -Realtime -MaxSamples 1| Export-Csv -Path "HQtime.csv"
Why not use the views? They have all the information that you need. Code below assumes you are connected to the vCenter.
$vmView = Get-View -ViewType VirtualMachine -Property Name,Config,Guest,Runtime
$hostView = Get-View -ViewType HostSystem -Property Name
$date = Get-Date
Foreach ($vm in $vmView)
{
If ($vm.Runtime.BootTime -ne $null)
{
$dateDiff = $date.Subtract($vmView.Runtime.BootTime)
}
Else
{
$dateDiff = $null
}
foreach ($h in $hostView)
{
If ($vm.Runtime.Host -eq $h.MoRef)
{
$tempHost = $($h.Name)
Break
}
}
$global:Export += #([PSCustomObject]#{
VMName = $($vm.Name)
ID = $($vm.Config.Uuid) #or use $($vm.MoRef)
Host = $tempHost
PowerState = $($vm.Guest.GuestState)
IPAddress = $($vm.Guest.IPAddress)
Notes = $($vm.Config.Annotations)
UptimeMinutes = $($dateDiff.TotalMinutes)
})
$dateDiff = $null
$tempHost = $null
}
$exportFileName = "C:\temp\VMInformation.csv"
$Export | Export-Csv $exportFileName -Force -NoTypeInformation

Powershell pipeline - Retrieve outputs from first cmdlet?

I am trying a few things in Powershell and what I don't manage to achieve is the following (in Exchange):
Get-User | Get-MailboxStatistics
But in the output I would like some fields/outputs from the "Get-User" cmdlet and some fields/outputs from the "Get-MailboxStatistics" cmdlet.
If anyone has an answer, I have searched the web but with no success as I've had difficulties explaining it in a few words.
Thanks in advance for your help.
Start with the execution of one cmdlet, pipe the results to Foreach-Object and then save a reference to the current object ($user), now execute the second command and save it in a variable as well. Create new object with properties from both objects.
You also need to filter users that have mailboxes, use the RecipientTypeDetails parameter.
$users = Get-User -RecipientTypeDetails UserMailox
$users | Foreach-Object{
$user = $_
$stats = Get-MailboxStatistics $user
New-Object -TypeName PSObject -Property #{
FirstName = $user.FirstName
LastName = $user.LastName
MailboxSize = $stats.TotalItemSize
ItemCount = $stats.ItemCount
}
}
I don't know if it is the best or optimal solution, but you certainly do it by saving actual user to variable in foreach:
$users = Get-User
$users | % { $user = $_; Get-MailboxStatistics $_ | %
{
"User name:{0} - some mailbox statistics: {1}" -f $user.SomePropertyOfUser, $_.SomePropertyOfMailbox
}
}
The first step (saving users into separate variable) is required only when working with Exchange cmdlets - as mentioned here, you cannot nest Exchange cmdlets in foreach...
This error is caused when executing the Exchange cmdlets through PowerShell remoting, which do not support more than one pipeline running at the same time. You may see this error when you pipe the output from a cmdlet to foreach-object, which then runs another cmdlet within its scriptblock.
$users = Get-User -RecipientTypeDetails UserMailbox
$users | Foreach-Object{ $user = $_; $stats = Get-MailboxStatistics $user.DistinguishedName; New-Object -TypeName PSObject -Property #{FirstName = $user.FirstName; LastName = $user.LastName;MailboxSize = $stats.TotalItemSize;ItemCount = $stats.ItemCount }}
I've had to add a specific field in input of Get-MailboxStatistics because remotely, I was having:
The following Error happen when opening the remote Runspace: System.Management.Automation.RemoteException: Cannot process argument transformation on parameter 'Identity'. Cannot convert the "gsx-ms.com/Users/userName1" value of type "Deserialized.Microsoft.Exchange.Data.Directory.Management.User" to type "Microsoft.Exchange.Configuration.Tasks.GeneralMailboxOrMailUserIdParameter".
Anyway, thank you both #Jumbo and #Shay-levy
Get-ADUser -identity ADACCOUNT | Select-object #{Name="Identity";Expression={$_.SamAccountName}} | Get-MailboxStatistics
For some reason the Identity parameter doesn't take pipelne input by value, only by property name. So in order to get it to work you can change the name of piped in data to match the parameter name of Identity. Then Get-MailboxStatistics finally knows how to treat the data your feeding it via the pipeline.