There was a post on the Minasi forum, where someone was trying to check which users had start/stop permissions on a given server. I knew SC would give the results, but it returns it in DACL format, which as far from readable by humans… So since I had some time to pass I decided to try to write a powershell script to translate the DACL into something human readable (We were having our floor lacquered, and the guy doing it, had a little extra lacquer, and decided to lacquer our hallway, thereby cutting me off from leaving the first floor of our house).
This function takes a service name and a computername as input, if no computername is given, it tries to look it up on the localmachine..
Function Get-ServiceDACL {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]
[String]$Servicename,
[Parameter(Mandatory=$false,Position=1)]
[String]$Computername= ".")
$sddl = Invoke-expression -Command "c:\Windows\System32\sc.exe \\$Computername sdshow $Servicename" # $Servicename
$sddl
$parts = $sddl -split(":")
#$parts.Length
$i = 0
Write-Host "Getting Service DACL for $ServiceName on $Computername"
While ($i -lt $parts.length) {
$part = $parts[$i]
Switch ($part) {
"D" { $i++; Parse-DACL $parts[$i] }
}
$i++
}
$sddl = ''
}
Function Parse-DACL {
Param([String]$SDDLIN)
[Array]$sddls = ($SDDLIN).split('(')
Foreach ($SDDLI in $sddls) {
#($SDDLI).replace(')';'')
#$SDDLI
$tokens = (($SDDLI).replace(')','')).split(";")
If ($tokens[5]) {
If ($tokens[5].length -gt 3) {
[wmi]$obj = 'Win32_SID.SID="{0}"' -f $($tokens[5])
$encoded = [System.Convert]::ToBase64String($obj.BinaryRepresentation)
$obj | Add-Member -MemberType NoteProperty -Name base64_sid -Value $encoded
Write-Host "$($obj.ReferencedDomainName)\$($obj.AccountName)" -ForegroundColor red
}
Else {
Write-Host "$($Trustees.get_item($tokens[5]))" -ForegroundColor red
}
" " + $AceType.get_item($tokens[0])
[regex]::split($tokens[2], '(.{2})') | % {Write-host " $($PermissionType.get_item($_)) `n" -NoNewline}
}
}
}
$AceType = @{"A" = "ACCESS ALLOWED";
"D" = "ACCESS DENIED";
"OA" = "OBJECT ACCESS ALLOWED: ONLY APPLIES TO A SUBSET OF THE OBJECT(S).";
"OD" = "OBJECT ACCESS DENIED: ONLY APPLIES TO A SUBSET OF THE OBJECT(S).";
"AU" = "SYSTEM AUDIT";
"AL" = "SYSTEM ALARM";
"OU" = "OBJECT SYSTEM AUDIT";
"OL" = "OBJECT SYSTEM ALARM";
"ML" = "MANDATORY LABEL"}
$AceFlags = @{
"CI" = "CONTAINER INHERIT: Child objects that are containers, such as directories, inherit the ACE as an explicit ACE.";
"OI" = "OBJECT INHERIT: Child objects that are not containers inherit the ACE as an explicit ACE.";
"NP" = "NO PROPAGATE: ONLY IMMEDIATE CHILDREN INHERIT THIS ACE.";
"IO" = "INHERITANCE ONLY: ACE DOESN'T APPLY TO THIS OBJECT; BUT MAY AFFECT CHILDREN VIA INHERITANCE.";
"ID" = "ACE IS INHERITED";
"SA" = "SUCCESSFUL ACCESS AUDIT";
"FA" = "FAILED ACCESS AUDIT"
}
$PermissionType = @{
"CC" = "Query Conf";
"DC" = "Change Conf";
"LC" = "QueryStat";
"SW" = "EnumDeps";
"RP" = "Start";
"WP" = "Stop";
"DT" = "Pause";
"LO" = "Interrogate";
"CR" = "UserDefined";
"GA" = "Generic All";
"GX" = "Generic Execute";
"GW" = "Generic Write";
"GR" = "Generic Read";
"SD" = "Standard Delete";
"RC" = "Read Control";
"WD" = "Write DAC";
"WO" = "Write Owner"
}
$Trustees = @{
"AO" = "Account operators";
"RU" = "Alias to allow previous Windows 2000";
"AN" = "Anonymous logon";
"AU" = "Authenticated users";
"BA" = "Built-in administrators";
"BG" = "Built-in guests";
"BO" = "Backup operators";
"BU" = "Built-in users";
"CA" = "Certificate server administrators";
"CG" = "Creator group";
"CO" = "Creator owner";
"DA" = "Domain administrators";
"DC" = "Domain computers";
"DD" = "Domain controllers";
"DG" = "Domain guests";
"DU" = "Domain users";
"EA" = "Enterprise administrators";
"ED" = "Enterprise domain controllers";
"WD" = "Everyone";
"PA" = "Group Policy administrators";
"IU" = "Interactively logged-on user";
"LA" = "Local administrator";
"LG" = "Local guest";
"LS" = "Local service account";
"SY" = "Local system";
"NU" = "Network logon user";
"NO" = "Network configuration operators";
"NS" = "Network service account";
"PO" = "Printer operators";
"PS" = "Personal self";
"PU" = "Power users";
"RS" = "RAS servers group";
"RD" = "Terminal server users";
"RE" = "Replicator";
"RC" = "Restricted code";
"SA" = "Schema administrators";
"SO" = "Server operators";
"SU" = "Service logon user"
}
#Example below queries the WinRM service on RemoteServer
Get-ServiceDACL winrm remotemgmt
I considered putting this in the script I wrote for checking Services/Scheduled Tasks/COM+ objects, but it just gave me too much output, so I decided to put this in a separate script, and tried to put a GUI around it, since it has been a while since I have opened Primal Forms.
The script takes a username, it then connects to all servers in your domain, and checks to see if the username you typed in has a connection to that server, it does so by querying Win32_LoggedOnUser (You will be surprised by how many connections you have to different machines)
The script requires Powershell V2, Quest AD cmdlets.
########################################################################
# Code Generated By: SAPIEN Technologies, Inc., PrimalForms 2009 v1.1.9.0
# Generated On: 08-09-2010 22:12
# Generated By: CTN
########################################################################
#----------------------------------------------
#region Application Functions
#----------------------------------------------
function OnApplicationLoad {
#Note: This function runs before the form is created
#Note: To get the script directory in the Packager use: Split-Path $hostinvocation.MyCommand.path
#Note: To get the console output in the Packager (Windows Mode) use: $ConsoleOutput (Type: System.Collections.ArrayList)
#Important: Form controls cannot be accessed in this function
#TODO: Add snapins and custom code to validate the application load
return $true #return true for success or false for failure
}
function OnApplicationExit {
#Note: This function runs after the form is closed
#TODO: Add custom code to clean up and unload snapins when the application exits
$script:ExitCode = 0 #Set the exit code for the Packager
}
#endregion
#----------------------------------------------
# Generated Form Function
#----------------------------------------------
function GenerateForm {
#----------------------------------------------
#region Import Assemblies
#----------------------------------------------
[void][reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
[void][reflection.assembly]::Load("System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
[void][reflection.assembly]::Load("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
[void][reflection.assembly]::Load("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
#endregion
#----------------------------------------------
#region Generated Form Objects
#----------------------------------------------
[System.Windows.Forms.Application]::EnableVisualStyles()
$form1 = New-Object System.Windows.Forms.Form
$label5 = New-Object System.Windows.Forms.Label
$label4 = New-Object System.Windows.Forms.Label
$label3 = New-Object System.Windows.Forms.Label
$label2 = New-Object System.Windows.Forms.Label
$label1 = New-Object System.Windows.Forms.Label
$progressbar1 = New-Object System.Windows.Forms.ProgressBar
$listbox1 = New-Object System.Windows.Forms.ListBox
$CheckBTN = New-Object System.Windows.Forms.Button
$Usernametxt = New-Object System.Windows.Forms.TextBox
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#endregion Generated Form Objects
#----------------------------------------------
# User Generated Script
#----------------------------------------------
$FormEvent_Load={
#TODO: Initialize Form Controls here
}
$handler_textbox1_TextChanged={
#TODO: Place custom script here
}
$handler_CheckBTN_Click={
#TODO: Place custom script here
$i = 1
$ErrorActionPreference ="silentlycontinue"
$Servers = get-QADComputer -SearchRoot 'appension.local/' -OSName "*Server*"
$progressbar1.Maximum(($Servers).length)
$label2.Text = $servers.length
Foreach ($server in $Servers) {
$users = get-WmiObject -computer $server.Name Win32_LoggedOnUser | select Antecedent -Unique
$label4.Text = $i
$i++
$label5.Text = $Server.name
$progressbar1.Increment("1")
Foreach ($user in $users) {
$domainname =([regex]::Match($user.Antecedent, 'Domain="(?<domain>.*?)"')).Groups["domain"].Value
$username = ([regex]::Match($user.Antecedent, 'Name="(?<name>.*?)"')).Groups["name"].Value
If ($username -like $Usernametxt.Text) {
#Write-Host "************* $($server.name) ********************"
$listbox1.Items.Add($Servers.name)
}
}
}
}
$handler_label1_Click={
#TODO: Place custom script here
}
$handler_listbox1_SelectedIndexChanged={
#TODO: Place custom script here
}
#----------------------------------------------
# Generated Events
#----------------------------------------------
$Form_StateCorrection_Load=
{
#Correct the initial state of the form to prevent the .Net maximized form issue
$form1.WindowState = $InitialFormWindowState
}
#----------------------------------------------
#region Generated Form Code
#----------------------------------------------
#
# form1
#
$form1.Controls.Add($label5)
$form1.Controls.Add($label4)
$form1.Controls.Add($label3)
$form1.Controls.Add($label2)
$form1.Controls.Add($label1)
$form1.Controls.Add($progressbar1)
$form1.Controls.Add($listbox1)
$form1.Controls.Add($CheckBTN)
$form1.Controls.Add($Usernametxt)
$form1.Text = "Check where user is logged in."
$form1.Name = "form1"
$form1.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$form1.ClientSize = New-Object System.Drawing.Size(418,358)
$form1.add_Load($FormEvent_Load)
#
# label5
#
$label5.TabIndex = 8
$label5.Size = New-Object System.Drawing.Size(149,18)
$label5.Location = New-Object System.Drawing.Point(142,302)
$label5.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$label5.Name = "label5"
#
# label4
#
$label4.TabIndex = 7
$label4.Size = New-Object System.Drawing.Size(31,18)
$label4.Location = New-Object System.Drawing.Point(61,303)
$label4.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$label4.Name = "label4"
#
# label3
#
$label3.TabIndex = 6
$label3.Size = New-Object System.Drawing.Size(27,18)
$label3.Text = " of"
$label3.Location = New-Object System.Drawing.Point(84,303)
$label3.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$label3.Name = "label3"
#
# label2
#
$label2.TabIndex = 5
$label2.Size = New-Object System.Drawing.Size(33,18)
$label2.Location = New-Object System.Drawing.Point(109,303)
$label2.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$label2.Name = "label2"
#
# label1
#
$label1.TabIndex = 4
$label1.Size = New-Object System.Drawing.Size(42,18)
$label1.Text = "Server"
$label1.Location = New-Object System.Drawing.Point(24,303)
$label1.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$label1.Name = "label1"
$label1.add_Click($handler_label1_Click)
#
# progressbar1
#
$progressbar1.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$progressbar1.Size = New-Object System.Drawing.Size(382,23)
$progressbar1.TabIndex = 3
$progressbar1.Location = New-Object System.Drawing.Point(24,323)
$progressbar1.Name = "progressbar1"
#
# listbox1
#
$listbox1.FormattingEnabled = $True
$listbox1.Size = New-Object System.Drawing.Size(201,225)
$listbox1.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$listbox1.Name = "listbox1"
$listbox1.Location = New-Object System.Drawing.Point(24,75)
$listbox1.TabIndex = 2
$listbox1.add_SelectedIndexChanged($handler_listbox1_SelectedIndexChanged)
#
# CheckBTN
#
$CheckBTN.TabIndex = 1
$CheckBTN.Name = "CheckBTN"
$CheckBTN.Size = New-Object System.Drawing.Size(75,23)
$CheckBTN.UseVisualStyleBackColor = $True
$CheckBTN.Text = "Check"
$CheckBTN.Location = New-Object System.Drawing.Point(150,20)
$CheckBTN.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$CheckBTN.add_Click($handler_CheckBTN_Click)
#
# Usernametxt
#
$Usernametxt.Size = New-Object System.Drawing.Size(100,20)
$Usernametxt.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
$Usernametxt.Text = "Username"
$Usernametxt.Name = "Usernametxt"
$Usernametxt.Location = New-Object System.Drawing.Point(24,24)
$Usernametxt.TabIndex = 0
$Usernametxt.add_TextChanged($handler_textbox1_TextChanged)
#endregion Generated Form Code
#----------------------------------------------
#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($Form_StateCorrection_Load)
#Show the Form
return $form1.ShowDialog()
} #End Function
#Call OnApplicationLoad to initialize
if(OnApplicationLoad -eq $true)
{
#Create the form
GenerateForm | Out-Null
#Perform cleanup
OnApplicationExit
}
A few weeks ago my admin account kept getting locked out, after I had changed my password.. So I assumed I had used it somewhere to either run a service or a scheduled task on a test server. But where???
So I decided to write a little PowerShell script to help me find out where, and give me a chance to be more proactive next time I need to change my Password, or the password of one of our service accounts.
So I decided to try to write a script that connects to all our servers, and list all services running under domain credentials, and do the same for scheduled tasks. In our environment we have an issue with some COM+ objects that are either running as a domain admin user, or as “interactive” meaning that a domain admin user has to be logged into a machine at all times for the app to work.. (Yes I have yelled and screamed at the developers).
So what this script does, it connects info from domain machines, and puts it in a Excel spreadsheet.
In order to run the script, you need to have Powershell V2, Quest AD cmdlet (preferably ver. 1.2 or above) and permissions on the remote machines to connect via WMI.
#==========================================================================
# NAME: GetServiceScheduledtaskandCom.ps1
#
# AUTHOR: Claus T Nielsen
# Version: 0.9
# Date: 07/09/10
#
# COMMENT:
# This script is based on a script by Stephen Wheet, a lot of the code has been rewritten, and
# and a bunch of code has been added.
# The script connects to remote computers, and lists all services running under domain accounts,
# it does the same for Scheduled Tasks and COM+ Applications.
#
# The Script required the QUEST AD cmdlets and excel installed on the computer
#
# Missing features: IIS APP Pool Credentials, Logged In Users
#==========================================================================
$domainname = (Get-QADRootDSE.Domain).Domain.ToString()
$searchroot = "appension.local/"
$ErrorActionPreference = "SilentlyContinue"
[System.Threading.Thread]::CurrentThread.CurrentCulture = "en-US"
$ErrorActionPreference = "SilentlyContinue"
$ExcelAPP = New-Object -comobject Excel.Application
$ExcelAPP.visible = $True
$ExcelWB = $ExcelAPP.Workbooks.Add()
$ServiceSheet = $ExcelWB.Worksheets.Item(1)
$ScheduledSheet = $ExcelWB.Worksheets.Item(2)
$COMPlusSheet = $ExcelWB.Worksheets.Item(3)
$ServiceSheet.Name = "Services"
$ScheduledSheet.Name = "Scheduled Tasks"
$COMPlusSheet.Name = "COM+"
# Accounts to ignore
$IgnoreAcct =
"NT AUTHORITY\LOCAL SERVICE",
"NT AUTHORITY\LOCALSERVICE",
"LocalSystem",
".\*",
"NT AUTHORITY\NETWORK SERVICE",
"NT AUTHORITY\NetworkService"
$DefaultCOMObjects =
'COM+ Utilities',
'COM+ QC Dead Letter Queue Listener',
'COM+ Explorer',
'COM+ Utilities (32 bit)',
'IIS Out-Of-Process Pooled Applications',
'.NET Utilities'
#Place Headers on out-put file
$ServiceSheet.Cells.Item(1,1) = "Server"
$ServiceSheet.Cells.Item(1,2) = "Service"
$ServiceSheet.Cells.Item(1,3) = "Account"
$ScheduledSheet.Cells.Item(1,1) = "Server"
$ScheduledSheet.Cells.Item(1,2) = "Task"
$ScheduledSheet.Cells.Item(1,3) = "Next Run Time"
$ScheduledSheet.Cells.Item(1,4) = "Account"
$COMPlusSheet.Cells.Item(1,1) = "Server"
$COMPlusSheet.Cells.Item(1,2) = "COM+ Name"
$COMPlusSheet.Cells.Item(1,3) = "Identity"
$d = $ServiceSheet.UsedRange
$d.Interior.ColorIndex = 19
$d.Font.ColorIndex = 11
$d.Font.Bold = $True
$l = $ScheduledSheet.UsedRange
$l.Interior.ColorIndex = 19
$l.Font.ColorIndex = 11
$l.Font.Bold = $True
$q = $COMPlusSheet.UsedRange
$q.Interior.ColorIndex = 19
$q.Font.ColorIndex = 11
$q.Font.Bold = $True
$intRowSer = 2
$intRowSch = 2
$intRowCom = 2
#Get all the servers from the specified OU
$Servers = get-QADComputer -SearchRoot $searchroot -OSName "*Server*" #| where {$_.name -like "appo*"} # change the container based on site.
Foreach ($server in $Servers ) {
#$ErrorActionPreference = "SilentlyContinue"
$serverFQDN = $server.dnsname
#Test ping server to make sure it's up before querying it
if (Test-Connection $serverFQDN -Quiet -Count 1){
Write-Host "`n ************* $serverFQDN Online `n" -ForegroundColor Red
Write-Host "****************** $($server.name) Services ******************"
# Get service info
$error.clear()
$services = gwmi win32_service -computer $serverFQDN -property name, startname, caption |
% {
$name = $_.Caption
$Acctname = $_.StartName
If ( $IgnoreAcct -notcontains $Acctname )
{
Write-host "$Name $Acctname"
$ServiceSheet.Cells.Item($intRowSer, 1) = $serverFQDN
$ServiceSheet.Cells.Item($intRowSer, 2) = $name
$ServiceSheet.Cells.Item($intRowSer, 3) = $Acctname
$intRowSer++
} #end If
} #end ForEach
#Write log if no access
if (!$?) {
$ServiceSheet.Cells.Item($intRowSer, 1) = $serverFQDN
$ServiceSheet.Cells.item($intRowSer, 2).Interior.ColorIndex = 3
$ServiceSheet.Cells.Item($intRowSer, 2) = "Access Denied/Offline"
$ServiceSheet.Cells.Item($intRowSer, 3) = $Error
#$errmsg = "$serverFQDN,No RPC server,ACCESS DENIED"
Write-Host $Error
$intRowSer++
} # end Error
$schtask = Schtasks.exe /query /s $serverFQDN /V /FO CSV | ConvertFrom-Csv
Write-Host "****************** $($server.name) Scheduled Tasks ******************"
if ($schtask) {
Foreach ($sch in $schtask) {
#$Sch."Run As User"
if ($Sch."Run As User" -like "$($domainname)*") {
Write-Host $serverFQDN ($Sch.TaskName).replace("\","") $Sch.'Run As User'
$ScheduledSheet.Cells.Item($intRowSch,1) = $serverFQDN
$ScheduledSheet.Cells.Item($intRowSch,2) = ($sch.TaskName).replace('\','')
$ScheduledSheet.Cells.Item($intRowSch,3) = $Sch.'Next Run Time'
$ScheduledSheet.Cells.Item($intRowSch,4) = $sch.'Run As User'
$intRowSch++
}
}
}
Write-Host "****************** $($server.name) COM+ Applications ******************"
#$targetComputer = $serverFQDN
$comAdmin = New-Object -comobject COMAdmin.COMAdminCatalog
$comAdmin.Connect($serverFQDN)
$apps = $comAdmin.GetCollection("Applications")
$apps.Populate()
foreach ($app in $apps) {
If ( $IgnoreAcct -notcontains ($app.Value("Identity")) -and ( $DefaultCOMObjects -notcontains ($app.Value("Name")) )) {
$q.Cells.Item($intRowCom,1) = $serverFQDN
$q.Cells.Item($intRowCom,2) = $app.Value("Name")
$q.Cells.Item($intRowCom,3) = $app.Value("Identity")
Write-Host $app.Value("Name") $app.Value("Identity")
$intRowCom++
}
}
}
Else
{
Write-Host "$serverFQDN ************* OFFLINE"
} #end Else
}
#end ForEach
$d.EntireColumn.AutoFit()
$l.EntireColumn.AutoFit()
$q.EntireColumn.AutoFit()
This looks very promising, going to give it a spin tomorrow when I get to work
http://www.lucd.info/2010/05/29/beyond-export-csv-export-xls/
A while back I posted a script that would take whatever input it got, into a sortable HTML table in a file.
Last night my family was here, and they wanted to see the Eurovision song contest thing, so I had some time to rewrite the script into a PowerShell V2 Advanced function, that supports pipeline input.
There are some examples in the code on how to use the function
I do not know what has happened to code highlighter, but it has suddenly decided to mess up the code, so it is not working on the site, so here is a link to the file.
Example of output:
download | new post
Here is my presentation from the 2010 Minasi conference.
Example #1
#Sessions
#Single Session
$Session = New-PSSession -ComputerName "computername"
#Multiple Sessions
$Session = New-PSSession -ComputerName "comp1","comp2".....
#Remove all Sessions
Remove-PSSession *
#Remove Named Session
Remove-PSSession $Session
#Using $session
Invoke-Command {ipconfig} -Session $Session
Enter-PSSession -Session $session
Example #2
$session = New-PSSession -ComputerName "compname"
Invoke-Command {Import-Module ActiveDirectory} -Session $session
Import-PSSession -Session $session -Module ActiveDirectory -Prefix "ctn"
notepad (Get-Module).path
Get-Command *ctn*
Example #1
List users that expires within X days
$DaysToExpire = 14
$MaxPassAge = (Get-QADObject (Get-QADRootDSE).defaultNamingContextDN).MaximumPasswordAge.days
[array]$a = Get-QADUser -Enabled -PasswordNeverExpires:$false -SizeLimit 0 -Email * |Select-Object Name,Email,@{Name="Expires";Expression={ $MaxPassAge - $_.PasswordAge.days }} | where {$_.Expires -lt 0} | Sort-Object expires
Example #2
Locate that Hyper-V Host
Get-QADComputer | Where {$_.OSname -match "2008"} | % { Get-Service -ComputerName $_.Name} | where {$_.Displayname -match "hyper"} | select Machinename, Displayname
#Kirk Munroe pointed out that Hyper-V actually registers ans SCP (Service Connection Point)
Get-QADObject -Name 'Microsoft Hyper-V' -Type serviceConnectionPoint | Get-QADComputer -Identity {$_.ParentContainerDN}
Example #3
Create test users and OU’s in AD
#Gets the default naming context
$RootDN = (Get-QADRootDSE).DefaultNamingContextDN
#Name of OU going to be created in the root of "AD"
$RootOUName = "MinasiTest"
#Create "root" OU
new-qadObject -ParentContainer $RootDN -type 'organizationalUnit' -NamingProperty 'ou' -name $RootOUName
#Create sub OU's, create as many as you like, you only need to change the -name property in the end of the line
new-qadObject -ParentContainer "OU=$RootOUName,$RootDN" -type 'organizationalUnit' -NamingProperty 'ou' -name 'Administrators'
new-qadObject -ParentContainer "OU=$RootOUName,$RootDN" -type 'organizationalUnit' -NamingProperty 'ou' -name 'Marketing'
new-qadObject -ParentContainer "OU=$RootOUName,$RootDN" -type 'organizationalUnit' -NamingProperty 'ou' -name 'Sales'
new-qadObject -ParentContainer "OU=$RootOUName,$RootDN" -type 'organizationalUnit' -NamingProperty 'ou' -name 'IT'
new-qadObject -ParentContainer "OU=$RootOUName,$RootDN" -type 'organizationalUnit' -NamingProperty 'ou' -name 'HR'
#
#
#
#Enter the DN path of the OU you want to add users to
#Note I manually put in the DN of an OU in my test environment, you will have to put one in that exists in your environment
#$OuPath = 'OU=Aprismo Users,DC=aprismo,DC=test'
$OuPath = "OU=$RootOUName,$RootDN"
#Number of users to create in each OU
$No = 5
Function AddUsers
{
param([string]$OUDN, [string]$OUName)
foreach($user in 1..$No)
{
$UserName = "Test$OUName$User"
$UserPassword = "P@ssw0rd123!"
$ExpiresOn = $((Get-Date).AddMonths(1))
$userDescription = "User added for Performance Testing on $(Get-date) and Expires on $ExpiresOn"
$user = New-QADUser -name $UserName `
-SamAccountName $UserName `
-Description $UserDescription `
-ParentContainer $OUDN `
-UserPassword $UserPassword
$user | Set-QADUser -AccountExpires ((Get-Date).AddMonths(1))
}
}
#This foreach loops through all OU's "below" $OUPath
Foreach ($OU in Get-QADObject -SearchRoot $OUPath -Type 'organizationalUnit'){
Addusers $OU.DN $OU.Name
}
Example #4
Rename Groups in AD
Get-QADGroup -Name "xyz*" | %{Set-QADGroup -Identity $_ -SamAccountName ($_.Name).Replace("xyz","abc") -whatif ;Rename-QADObject -Identity $_ -NewName ($_.Name).Replace("xyz","abc") -WhatIf }
Example #5
Output a list of servers in a Excel documents, with ping stats and if the machine is disabled/enabled
#$serverlist = Get-QADComputer -LdapFilter '(!(userAccountControl:1.2.840.113556.1.4.803:=2))' | where {$_.Osname -like "*server*"}
$serverlist = Get-QADComputer -IncludedProperties pwdLastSet -SizeLimit 0 | where {$_.Osname -like "*server*"}
$erroractionpreference = "SilentlyContinue"
$a = New-Object -comobject Excel.Application
$a.visible = $True
$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)
$c.Cells.Item(1,1) = "Machine Name"
$c.Cells.Item(1,2) = "OS Name"
$c.Cells.Item(1,3) = "IP Address"
$c.Cells.Item(1,4) = "Ping Status"
$c.Cells.Item(1,5) = "Password last set"
$c.Cells.Item(1,6) = "Enabled/Disabled"
$c.Cells.Item(1,7) = "Physical/Virtual"
$d = $c.UsedRange
$d.Interior.ColorIndex = 19
$d.Font.ColorIndex = 11
$d.Font.Bold = $True
$intRow = 2
$colComputers = $serverlist
foreach ($strComputer in $colComputers)
{
$c.Cells.Item($intRow, 1) = $strComputer.Name
$ping = new-object System.Net.NetworkInformation.Ping
$Reply = $ping.send($strComputer.Name)
if ($Reply.status –eq “Success”)
{
$machineType = Get-WmiObject -ComputerName $strComputer.Name -Class Win32_BIOS
If ($strComputer.AccountIsDisabled) {$enab = "Disabled"} else {$enab = "Enabled"}
if ($strComputer.pwdLastSet -le (Get-Date).AddDays(-90)) {$age = "Older than 90 Days" ; $fgColor = 3} else {$age = "Less than 90 days"; $fgColor = 0}
if ($machineType.Serialnumber -like "*vmware*") {$type = "VMware"}
Elseif ($machineType.Version -like "*VRTUAL*") {$type = "Hyper-V"}
Elseif (!($machineType.Version)) {$type = "N/A"}
else {$type = "Physical"}
$c.Cells.Item($intRow, 2) = $strComputer.OSName
$c.Cells.Item($intRow, 3) = $Reply.Address.ToString()
$c.Cells.Item($intRow, 4) = "Online"
$c.Cells.item($intRow, 5).Interior.ColorIndex = $fgColor
$c.Cells.Item($intRow, 5) = $age
$c.Cells.Item($intRow, 6) = $enab
$c.Cells.Item($intRow, 7) = $type
$Reply = ""
$intRow = $intRow + 1
}
else
{
$machineType = Get-WmiObject -ComputerName $strComputer.Name -Class Win32_BIOS
If ($strComputer.AccountIsDisabled) {$enab = "Disabled"} else {$enab = "Enabled"}
if ($strComputer.pwdLastSet -le (Get-Date).AddDays(-90)) {$age = "Older than 90 Days" ; $fgColor = 3} else {$age = "Less than 90 days"; $fgColor = 0}
if ($machineType.Serialnumber -like "*vmware*") {$type = "VMware"}
Elseif (!($machineType.Version)) {$type = "N/A"}
Elseif ($machineType.Version -like "*VRTUAL*") {$type = "Hyper-V"}
else {$type = "Physical"}
$c.Cells.Item($intRow, 2) = $strComputer.OSName
$c.Cells.Item($intRow, 3) = $Reply.Address.ToString()
$c.Cells.Item($intRow, 4) = "Offline"
$c.Cells.item($intRow, 5).Interior.ColorIndex = $fgColor
$c.Cells.Item($intRow, 5) = $age
$c.Cells.Item($intRow, 6) = $enab
$c.Cells.Item($intRow, 7) = $type
$Reply = ""
$intRow = $intRow + 1
}
$d.EntireColumn.AutoFit()
}
Example #1 (From Lee Holmes’ Powershell cookbook)
“Compile C# code on the fly”
$code =@'
using System.Management.Automation;
[Cmdlet("Write", "InputObject")]
public class MyWriteInputObjectCmdlet : Cmdlet
{
[Parameter]
public string Parameter1;
[Parameter(Mandatory = true, ValueFromPipeline=true)]
public string InputObject;
protected override void ProcessRecord()
{
if (Parameter1 != null)
WriteObject(Parameter1 + ":" + InputObject);
else
WriteObject(InputObject);
}
}
'@
Add-Type -TypeDefinition $code -OutputAssembly .\ExampleModule.dll
Import-Module .\ExampleModule.dll
Example #2 (From Lee Holmes’ Powershell cookbook)
Showing how static functions are available directly
$source = @"
public class BasicTest
{
public static int Add(int a, int b)
{
return (a + b);
}
public int Multiply(int a, int b)
{
return (a * b);
}
}
"@
Add-Type -TypeDefinition $source
[BasicTest]::Add(4, 3)
$basicTestObject = New-Object BasicTest
$basicTestObject.Multiply(5, 2)
Example #3
Access .Net function to move mouse, in order to prevent screensaver from kicking in.
Function Move-Mouse {
param($minutes = 60)
for ($i = 0; $i -lt $minutes; $i++) {
Start-Sleep -Seconds 60
$Pos = [System.Windows.Forms.Cursor]::Position
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point((($Pos.X) + 1) , $Pos.Y)
}
}
Here are some of the scripts that I used during the demonstration in VA Beach.
Profiles:
Example #1
function prompt
{
"Xenophane " + $(get-location) + ">"
}
Example #2
function prompt
{
"Processes " + (Get-Process).Count+ " " + $(get-location) + "> "
}
Example #3 (Example taken from website)
function Prompt
{
$id = 1
$historyItem = Get-History -Count 1
if($historyItem)
{
$id = $historyItem.Id + 1
}
Write-Host -ForegroundColor DarkGray `n[$(Get-Location)]
Write-Host -NoNewLine PS$id
$host.UI.RawUI.WindowTitle = $(Get-Location)
`b
}
Example #4 (Overdone one)
function prompt
{
[wmi]$Global:Cdrive=Get-WmiObject -query "Select * from win32_logicaldisk where deviceid='c:'"
#Define Cdrive as global variable, which is type cast as a wmi
$processcount=(Get-Process).Count
#Define variable processcount as number of processes running
$cpuload=(Get-WmiObject win32_processor).loadpercentage
#cpuload is defined as a variable
$diskinfoC=" Free C: "+"{0:N2}" -f (($global:Cdrive.freespace/1gb)/($global:cdrive.size/1gb)*100)+"%"
#diskinfoC is defined, {0:N2} is .NET for 2 decimal places, -f is a the "format" property of the string object.
# Then the amount of free space on drive C is divided by the size of drive C multiplies by 100 to get
#the percentage of free space.
$time=Get-WmiObject -class Win32_OperatingSystem
#Define $time is object Win32_OperatingSystem
$t=$time.ConvertToDateTime($time.Lastbootuptime)
#Define #t as the result of the convertion of LastBootuptime into a readable dateTime format.
[TimeSpan]$uptime=New-TimeSpan $t $(get-date)
#Typecast the variable $uptime as a [timespan], the timespan cmdlet in powershell is a way to do date arithmetic in ps
#This way we can compare our variable $t (Which was Lastbootuptime) and the current time Get-date cmdlet
$up="$($uptime.days)d $($uptime.hours)h $($uptime.minutes)m $($uptime.seconds)s"
#define variable $up to display the uptime in days/hours/minuted/seconds
$TextToDisplay="CPU:"+$cpuload+"% Processes:" + $processcount + $diskinfoC+ " " + $diskinfoG+ " "+ ([char]0x25b2)+$up +" "+(Get-Date -format g)
#define one variable that contains all the data we collected so far.
Write-Host -fore red $TextToDisplay
#Write the information to the screen in red
Write-Host "My PoSh:" $(get-location) -nonewline
#Display the regular prompt.
}

Categories
Tag Cloud
Blog RSS
Comments RSS
Last 50 Posts
Back
Void « Default
Life
Earth
Wind
Water
Fire
Light 