Differences between revisions 40 and 51 (spanning 11 versions)
Revision 40 as of 2020-09-21 14:46:14
Size: 9302
Editor: scot
Comment:
Revision 51 as of 2021-02-11 00:15:42
Size: 14209
Editor: scot
Comment:
Deletions are marked like this. Additions are marked like this.
Line 86: Line 86:
Get-ADUser -Filter * -SearchBase "dc=home,dc=scotnpatti,dc=com" -ResultPageSize 0 -Prop CN,samaccountname,lastLogonTimestamp |
     select CN, samaccountname,@{n="lastLogonDate";e={[datetime]::FromFileTime($_.LastLogonTimestamp)}}
# This method looks like it should work, but LastLogon is stored at each domain controller, and the domain controller you are
# using, may not have ever been logged into by the user
#Get-ADUser -Filter * -SearchBase "dc=home,dc=scotnpatti,dc=com" -ResultPageSize 0 -Prop CN,samaccountname,lastLogonTimestamp |
# select CN, samaccountname,@{n="lastLogonDate";e={[datetime]::FromFileTime($_.LastLogonTimestamp)}}

# INSTEAD USE THIS METHOD
Import-Module ActiveDirectory
function Get-LastLogonEvents
{
    $UserList = New-Object System.Collections.ArrayList
    $dcs = Get-ADDomainController -Filter {Name -like "*"}
    $users = Get-ADUser -Filter *
    $time = 0
    foreach($user in $users)
    {
        foreach($dc in $dcs)
        {
            $hostname = $dc.HostName
            $currentUser = Get-ADUser $user.SamAccountName | Get-ADObject -Server $hostname -Properties lastLogon
            if($currentUser.LastLogon -gt $time)
            {
                $time = $currentUser.LastLogon
            }
        }
        
        $dt = [DateTime]::FromFileTime($time)
        $temp = New-Object System.Object
        $temp | Add-Member -MemberType NoteProperty -Name "SamAccountName" -Value $user.SamAccountName
        $temp | Add-Member -MemberType NoteProperty -Name "LastLogon" -Value $dt
        $UserList.Add($temp) | Out-Null
        $time = 0
    }
    return $UserList
}
$myList = Get-LastLogonEvents | Sort-Object LastLogon | FT SamAccountName, LastLogon
Write-Output $myList
Line 103: Line 137:
}}}

== List AD Computer accounts and the last time they have been logged in ==
{{{#!highlight powershell
# This method looks like it should work, but LastLogon is stored at each domain controller, and the domain controller you are
# using, may not have ever been logged into by the user
#Get-ADUser -Filter * -SearchBase "dc=home,dc=scotnpatti,dc=com" -ResultPageSize 0 -Prop CN,samaccountname,lastLogonTimestamp |
# select CN, samaccountname,@{n="lastLogonDate";e={[datetime]::FromFileTime($_.LastLogonTimestamp)}}

# INSTEAD USE THIS METHOD
Import-Module ActiveDirectory
function Get-LastComputerLogonEvents
{
    $ComputerList = New-Object System.Collections.ArrayList
    $dcs = Get-ADDomainController -Filter {Name -like "*"}
    Write-Output $dcs
    $computers = Get-AdComputer -Filter *
    $time = 0
    foreach($computer in $computers)
    {
        foreach($dc in $dcs)
        {
            $hostname = $dc.HostName
            $currentComputer = Get-ADComputer $computer.SamAccountName | Get-ADObject -Server $hostname -Properties lastLogon
            if($currentComputer.LastLogon -gt $time)
            {
                $time = $currentComputer.LastLogon
            }
        }
        
        $dt = [DateTime]::FromFileTime($time)
        $temp = New-Object System.Object
        $temp | Add-Member -MemberType NoteProperty -Name "SamAccountName" -Value $computer.SamAccountName
        $temp | Add-Member -MemberType NoteProperty -Name "LastLogon" -Value $dt
        $ComputerList.Add($temp) | Out-Null
        $time = 0
    }
    return $ComputerList
}
$myList = Get-LastComputerLogonEvents | Sort-Object LastLogon | FT SamAccountName, LastLogon
Write-Output $myList
Line 163: Line 238:
                                   $l = Get-DhcpServerv4Lease -ScopeId 216.249.119.0 -ComputerName "csdc01" -ClientId $a;                                    $l = Get-DhcpServerv4Lease -ScopeId 10.10.4.0 -ComputerName "ruth" -ClientId $a;
Line 167: Line 242:
}}}

== List SCVMM VMs/Templates and their Ownership - Change Ownership ==
{{{#!highlight powershell
Get-SCVMTemplate | ? { $_.Owner -eq "DOMAIN\X" } | Set-SCVMTemplate -Owner "DOMAIN\Y"
Get-SCVirtualMachine | ? { $_.Owner -eq "DOMAIN\X" } | Set-SCVirtualMachine -Owner "X\Y"
}}}

== List SCVMM VMs/Templates LimitCPUForMigration and Set to allow migration ==

Note: Setting LimitCPUForMigration = $true means that we are limiting the CPU so that it can migrate to different versions of the same CPU.

{{{#!highlight powershell
Get-SCVMTemplate | ? { $_.LimitCPUForMigration -eq $false } | Set-SCVMTemplate -LimitCPUForMigration $true
Get-SCVirtualMachine | ? { $_.LimitCPUForMigration -eq $false } | Set-SCVirtualMachine -LimitCPUForMigration $true
Line 238: Line 328:

== Power Shell Script to List Network Adapters on a VM ==

Note: When looking at the !VirtualNetworkAdapterType value, "Emulated" means that it is "legacy" network adapter and "Synthetic" means its a non-legacy adapter.

{{{#!highlight powershell
Get-SCVirtualMachine | ? { $_.Name -like "*pfsense*" } | Get-SCVirtualNetworkAdapter
}}}

== List VLANs for all CPTR 427 Virtual Machines in System Center ==

{{{#!highlight powershell
Get-SCVirtualMachine |
    ? { $_.Name -like "*427*" } |
    SELECT Name,@{label="VlanID";expression={($_.VirtualNetworkAdapters).VlanID}} |
    Sort-Object Name | Export-Csv -Path .\VlanData.csv
}}}

== Revoke all MAC addresses Back to the Pool ==

This came up as a maintenance issue when we lost some VMs, but not the configurations

{{{#!highlight powershell
$HostGroup = Get-SCVMHostGroup | where { $_.Path -eq "All Hosts\Server2016" }
$MACAddressPool = Get-SCMACAddressPool -VMHostGroup $HostGroup
$MACAddress = Get-SCMACAddress -MACAddressPool $MACAddressPool[0]
ForEach ($item in $MACAddress) {
    Revoke-SCMACAddress $item
}
}}}

Here is a list of Power Shell Scripts that are too cool to ignore

For the uninitiated:

Symbol

Meaning

%

shortcut for foreach object

$_

current object in the pipeline

Get-Member

Will list the fields of the object you send it

Sort-Object -Property [property name]

Will sort the objects you send in by the property name(s) which can be a comma separated list

Where-Object {$_.property -like '*string*'}

Will filter the objects. Also short cut notation: ? {$_.property -like '*string*'}

Get-Command -Module PSWindowsUpdate

Lists all the commands in the PSWindowsUpdate module

Windows

Expand all zip files into directories with zip name

   1 $list = Get-ChildItem | ? { $_.Name -like "*.zip" } | select Name
   2 foreach ($line in $list) {
   3     $parts = $line.Name.Split(".")
   4     $outDir = ".\" + $parts[0]
   5     $inFile = $line.Name
   6     mkdir $outDir
   7     Expand-Archive $inFile -DestinationPath $outDir 
   8 }

List of Listening Ports with their owning programs

   1 $listening = (Get-NetTCPConnection | ? {($_.State -eq "Listen") -and ($_.RemoteAddress -eq "0.0.0.0")})
   2 foreach ($l in $listening) {
   3     $procid = $l.OwningProcess
   4     $proc = Get-Process -PID $procid | SELECT ID,ProcessName
   5     Write-Host $($l.LocalPort) "||" $($procid) "||" $proc.ProcessName
   6 }

List Memory Installed

   1 Get-WmiObject win32_physicalmemory | Format-Table Manufacturer,Banklabel,Configuredclockspeed,Devicelocator,Capacity,Serialnumber -autosize

List object from Registry - namely version of .NET installed

   1 gci 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' | sort pschildname -des | foreach-object {$_.name; $_.GetValue("Version");}

Remote commands

   1 Invoke-Command -ComputerName eve -ScriptBlock { date }

Replace a string in a file using a regular expression

So I downloaded a bunch of files from "the way back machine" site and I needed to update the hard-coded links to be relative site links. The following little script did it for me.

   1 $files = ls Level*.html
   2 foreach ($item in $files) {
   3     (Get-Content -path $item) | % { $_ -Replace '(https://web.archive.org/nebula/level)([0123456789]{2})/', 'Level$2.html' } | Set-Content $item
   4 } 

AD Scripts

Add User to the Active Directory as a batch

   1 New-ADUser -Name "A a" -GivenName "A" -Surname "a" -SamAccountName "ab" -Path "OU=OU_Students,DC=cs,DC=southern,DC=edu" -AccountPassword (ConvertTo-SecureString "z36Hynyghg" -AsPlainText -Force) -Enabled $true

See: Excel Example

List of AD accounts and the last time they logged in

   1 # This method looks like it should work, but LastLogon is stored at each domain controller, and the domain controller you are 
   2 # using, may not have ever been logged into by the user
   3 #Get-ADUser -Filter * -SearchBase "dc=home,dc=scotnpatti,dc=com" -ResultPageSize 0 -Prop CN,samaccountname,lastLogonTimestamp | 
   4 #     select CN, samaccountname,@{n="lastLogonDate";e={[datetime]::FromFileTime($_.LastLogonTimestamp)}} 
   5 
   6 # INSTEAD USE THIS METHOD
   7 Import-Module ActiveDirectory
   8 function Get-LastLogonEvents
   9 {
  10     $UserList = New-Object System.Collections.ArrayList
  11     $dcs = Get-ADDomainController -Filter {Name -like "*"}
  12     $users = Get-ADUser -Filter *
  13     $time = 0
  14     foreach($user in $users)
  15     {
  16         foreach($dc in $dcs)
  17         {
  18             $hostname = $dc.HostName
  19             $currentUser = Get-ADUser $user.SamAccountName | Get-ADObject -Server $hostname -Properties lastLogon
  20             if($currentUser.LastLogon -gt $time)
  21             {
  22                 $time = $currentUser.LastLogon
  23             }
  24         }
  25         
  26         $dt = [DateTime]::FromFileTime($time)
  27         $temp = New-Object System.Object
  28         $temp | Add-Member -MemberType NoteProperty -Name "SamAccountName" -Value $user.SamAccountName
  29         $temp | Add-Member -MemberType NoteProperty -Name "LastLogon" -Value $dt
  30         $UserList.Add($temp) | Out-Null
  31         $time = 0
  32     }
  33     return $UserList
  34 }
  35 $myList = Get-LastLogonEvents | Sort-Object LastLogon | FT SamAccountName, LastLogon
  36 Write-Output $myList

Delete AD User accounts that have not been used in X days

   1 $DaysAgo = (Get-Date).AddDays(-180)
   2 #Get-ADUser -Filter {Enabled -eq $True} -Properties LastLogonDate | ? {($_.LastLogonDate -le $DaysAgo)  } | FT Name, SamAccountName, DistinguishedName, LastLogonDate
   3 Get-ADUser -Filter {Enabled -eq $True} -Properties LastLogonDate | ? {($_.LastLogonDate -le $DaysAgo)  } | Remove-ADUser -Confirm

Delete AD Computer accounts that have not been used in X days

   1 $YearAgo = (Get-Date).AddDays(-370)
   2 Get-ADComputer -Filter * -Properties * | ? {$_.LastLogonDate -le $YearAgo } | Remove-ADObject -Recursive -Confirm 
   3 #Get-ADComputer -Filter * -Properties * | ? {$_.LastLogonDate -le $YearAgo } | FT Name, LastLogonDate -AutoSize

List AD Computer accounts and the last time they have been logged in

   1 # This method looks like it should work, but LastLogon is stored at each domain controller, and the domain controller you are 
   2 # using, may not have ever been logged into by the user
   3 #Get-ADUser -Filter * -SearchBase "dc=home,dc=scotnpatti,dc=com" -ResultPageSize 0 -Prop CN,samaccountname,lastLogonTimestamp | 
   4 #     select CN, samaccountname,@{n="lastLogonDate";e={[datetime]::FromFileTime($_.LastLogonTimestamp)}} 
   5 
   6 # INSTEAD USE THIS METHOD
   7 Import-Module ActiveDirectory
   8 function Get-LastComputerLogonEvents
   9 {
  10     $ComputerList = New-Object System.Collections.ArrayList
  11     $dcs = Get-ADDomainController -Filter {Name -like "*"}
  12     Write-Output $dcs
  13     $computers = Get-AdComputer -Filter *
  14     $time = 0
  15     foreach($computer in $computers)
  16     {
  17         foreach($dc in $dcs)
  18         {
  19             $hostname = $dc.HostName
  20             $currentComputer = Get-ADComputer $computer.SamAccountName | Get-ADObject -Server $hostname -Properties lastLogon
  21             if($currentComputer.LastLogon -gt $time)
  22             {
  23                 $time = $currentComputer.LastLogon
  24             }
  25         }
  26         
  27         $dt = [DateTime]::FromFileTime($time)
  28         $temp = New-Object System.Object
  29         $temp | Add-Member -MemberType NoteProperty -Name "SamAccountName" -Value $computer.SamAccountName
  30         $temp | Add-Member -MemberType NoteProperty -Name "LastLogon" -Value $dt
  31         $ComputerList.Add($temp) | Out-Null
  32         $time = 0
  33     }
  34     return $ComputerList
  35 }
  36 $myList = Get-LastComputerLogonEvents | Sort-Object LastLogon | FT SamAccountName, LastLogon
  37 Write-Output $myList

Adding DNS records to Windows DNS - For CPTR 446 class

   1 Import-Csv googleips.csv | ForEach-Object {
   2     Add-DnsServerResourceRecordA -Name $_.DNSName -ComputerName dc1.cs.southern.edu  -ZoneName cs.southern.edu $_.IP
   3 }

Setting up a Group Managed Service Account

An account that is automatically managed (e.g. password updates) by the domain. See get-help New-AdServiceAccount

   1 # Adds the required root key to the key distribution service
   2 Add-KdsRootKey -EffectiveTime ((get-date).AddHours(-10))
   3 #Create an account:
   4 New-ADServiceAccount Sql-Srv-Acct -DNSHostName Sql-Srv-Acct.home.scotpatti.com -PrincipalsAllowedToRetrieveManagedPassword "Domain Controllers"
   5 #Install account on rita.home.scotnpatti.com
   6 Install-ADServiceAccount -Identity 'Sql-Srv-Acct'

SCVMM Powershell scripts

I needed this once when I was trying to refresh the Library share. It failed on refresh with an error saying that a DVD was in use and wouldn't refresh until it was no longer in use. The following commands allowed me to identify the machines.

In general all of these need:

   1 Import-Module VirtualMachineManager

Get a list of Virtual Machines that have a DVD attached

   1 Get-SCVMMServer -ComputerName Samuel
   2 Get-SCVirtualMachine | Get-SCVirtualDVDDrive | Where-Object {$_.Connection -eq "ISOImage"} | Select Name, Connection, ISO

List VMs at the end of the semester to be deleted

   1 Get-SCVirtualMachine | Select Name, MarkedAsTemplate, Owner | Sort-Object -Property Owner, Name | Export-Csv -Path .\vms2019w.csv

Get a list of VM Mac Addresses for CPTR 427

   1 Get-SCVirtualMachine | Where-Object { $_.Name -like "*427*" } | select -ExpandProperty VirtualNetworkAdapters | select MacAddress

Get a list of IP address for SCVMM

   1 Get-SCMACAddress -Assigned | Format-Table -Property `
   2 @{label="MAC address"; expression={$_.Name};                  width=18},
   3 @{label="Name";        expression={$_.Description};           width=30},
   4 @{label="IP address";  expression={$a = $_.Address -replace ":", "";
   5                                    $l = Get-DhcpServerv4Lease -ScopeId 10.10.4.0 -ComputerName "ruth" -ClientId $a;
   6                                    $l.IPAddress};             width=16}
   7 
   8 #Get-DhcpServerv4Lease -ScopeId 216.249.119.0 -ComputerName 'csdc01' -ClientId '001DD8B71C28'

List SCVMM VMs/Templates and their Ownership - Change Ownership

   1 Get-SCVMTemplate | ? { $_.Owner -eq "DOMAIN\X" } | Set-SCVMTemplate -Owner "DOMAIN\Y"
   2 Get-SCVirtualMachine | ? { $_.Owner -eq "DOMAIN\X" } | Set-SCVirtualMachine -Owner "X\Y"

List SCVMM VMs/Templates LimitCPUForMigration and Set to allow migration

Note: Setting LimitCPUForMigration = $true means that we are limiting the CPU so that it can migrate to different versions of the same CPU.

   1 Get-SCVMTemplate | ? { $_.LimitCPUForMigration -eq $false } | Set-SCVMTemplate -LimitCPUForMigration $true
   2 Get-SCVirtualMachine | ? { $_.LimitCPUForMigration -eq $false } | Set-SCVirtualMachine -LimitCPUForMigration $true

Setting up a Windows 2019 Server for the first time

  1. Install the server - follow prompts.
  2. Setup the AVMA key as shown below OR use sconfig in the next step.

   1 # Install the AVMA key.
   2 slmgr /ipk TNK62-RXVTB-4P47B-2D623-4GF74
   3 
   4  1. 
   5 
   6 #First run sconfig and setup the name, timezone and network, remote management and remote desktop. You can also setup windows update from here. 
   7 
   8 # Next we need to install Windows update and get it started.
   9 # This will install nuget package too.
  10 Install-Module PSWindowsUpdate
  11 
  12 # Now start the update process
  13 #   First we'll look at what updates are there
  14 Get-WUInstall 
  15 #   Now install them
  16 Install-WindowsUpdate

See the NAT setup near the bottom! That appears to have negated the need to change firewall rules. Also, I was not able to connect to the system via Server Manager right away. But a few minutes later, I could. No changes were made. But for posterity, they are here:

   1 # To turn on or off the firewall 
   2 Get-NetFirewallProfile
   3 # to set firewall on or off
   4 Set-NetFirewallProfile -Name Domain,Public,Private -Enabled True
   5 
   6 #Te get/set the firewall rule for private networks to allow any machine on a private network.
   7 Get-NetFirewallRule | ? {$_.DisplayGroup -like "Windows Remote Management*" -and $_.Profile -like "*Private*"} | Get-NetFirewallAddressFilter #Shows the address filter
   8 Get-NetFirewallRule | ? {$_.DisplayGroup -like "Windows Remote Management*" -and $_.Profile -like "*Private*"} | Set-NetFirewallRule -RemoteAddress 192.168.1.0/24

Using Server Manager, install AD DS

Power shell to list of VM hard drives sizes

   1 $vms = Get-SCVirtualDiskDrive -all
   2 foreach ($v in $vms)
   3 {
   4     $d = $v | select -ExpandProperty VirtualHardDisk
   5     Write-Output "$($v.Name), $($d.Size)"
   6 }

List the amount of memory used by virtual machines

   1 Get-SCVirtualMachine | ForEach-Object { $size += $_.Memory }

Resources:

Power Shell Scripts to create a NAT network (without DHCP) on Windows 10

   1 New-VMSwitch -SwitchName "CPTE230" -SwitchType Internal
   2 Get-VMSwitch #just for show
   3 Get-NetAdapter #get the ifIndex of your vEthernet adapter e.g. 67
   4 New-NetIPAddress -IPAddress 192.168.1.1 -PrefixLength 24 -InterfaceIndex 67 #Using the network ifIndex found above, e.g. 67
   5 New-NetNat -Name CPTE230NAT -InternalIPInterfaceAddressPrefix 192.168.1.0/24 #create the NAT 

Power Shell Script to List Network Adapters on a VM

Note: When looking at the VirtualNetworkAdapterType value, "Emulated" means that it is "legacy" network adapter and "Synthetic" means its a non-legacy adapter.

   1 Get-SCVirtualMachine | ? { $_.Name -like "*pfsense*" } | Get-SCVirtualNetworkAdapter

List VLANs for all CPTR 427 Virtual Machines in System Center

   1 Get-SCVirtualMachine | 
   2     ? { $_.Name -like "*427*" } | 
   3     SELECT Name,@{label="VlanID";expression={($_.VirtualNetworkAdapters).VlanID}} | 
   4     Sort-Object Name | Export-Csv -Path .\VlanData.csv

Revoke all MAC addresses Back to the Pool

This came up as a maintenance issue when we lost some VMs, but not the configurations

   1 $HostGroup = Get-SCVMHostGroup | where { $_.Path -eq "All Hosts\Server2016" }
   2 $MACAddressPool = Get-SCMACAddressPool -VMHostGroup $HostGroup
   3 $MACAddress = Get-SCMACAddress -MACAddressPool $MACAddressPool[0] 
   4 ForEach ($item in $MACAddress) {
   5     Revoke-SCMACAddress $item 
   6 }

WindowsAdministration/PowerShellScripts (last edited 2024-08-30 00:21:07 by scot)