This commit is contained in:
Zack Meier
2026-04-15 15:42:41 -05:00
parent 74edcc4d9a
commit 03dba08135
146 changed files with 9119 additions and 1 deletions
+4
View File
@@ -0,0 +1,4 @@
# Register Ado Artifact Repo
$url='https://pkgs.dev.azure.com/ndgov/_packaging/ITD3/nuget/v2'
Register-PSRepository -Name "NDGOV_ADO" -SourceLocation $url -PublishLocation $url -InstallationPolicy Trusted -Credential $AdoCred
+43
View File
@@ -0,0 +1,43 @@
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $M365Cred -Authentication Basic -AllowRedirection
Import-PSSession $Session -DisableNameChecking
## Get All Devices and Mailboxes metadata, store in memory/variable
## Torey should verify I'm pulling ActiveSync devices correctly:
#$AllDevices = Get-MobileDevice # All Devices
$AllDevices = Get-MobileDevice -ActiveSync # Only ActiveSync I hope
$AllMailboxes = Get-Mailbox -ResultSize Unlimited
# Loop through each device, get a part of its identity, and match that identity part with a mailbox, 2400 devices took about 20 minutes to run
$result = @()
$count = 0
ForEach ($Device in $AllDevices) {
$count++
write-warning ($count.tostring() + '/' + $AllDevices.Count)
#clear loop variables
$Mailbox = $null
$DeviceDisplayName = $null
$ADUser = $null
$DeviceDisplayName = $Device.Identity.split('\')[0]
$Mailbox = $AllMailboxes | Where-Object DisplayName -eq $DeviceDisplayName
If($Mailbox){
$ADUser = Get-ADUser -Identity $Mailbox.PrimarySmtpAddress.split('@')[0] -Properties CanonicalName
}
# create custom object to show only information we want
$obj = [PSCustomObject]@{
DeviceDisplayName = $DeviceDisplayName;
DeviceAccessState = $Device.DeviceAccessState;
MailboxName = If($Mailbox){$Mailbox.Name};
PrimarySmtpAddress = If($Mailbox){$Mailbox.PrimarySmtpAddress};
Agency = If($Mailbox){$ADuser.CanonicalName.split('/')[1]};
DeviceFriendlyName = $Device.FriendlyName;
DeviceUserAgent = $Device.DeviceUserAgent;
}
# store new object in array
$result += $obj
}
Write-Output $result
+131
View File
@@ -0,0 +1,131 @@
<#
.Synopsis
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
#>
function Add-ITDCredentialToCsv
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)]
[string]
$VariableName
)
begin
{
}
process
{
$NewCredential=Get-Credential
$obj=[PSCustomObject]@{
'VariableName' = $VariableName
'Username' = $NewCredential.UserName;
'SecureString' = $NewCredential.Password | ConvertFrom-SecureString;
}
$Obj | export-csv ($env:USERPROFILE + "\Documents\accts.csv") -Force -Append
}
end
{
}
}
<#
.SYNOPSIS
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
function Update-ITDCredentialCsv
{
[CmdletBinding()]
Param
(
[string[]]
$VariableName,
[switch]
$All
)
begin
{
$csv = Import-Csv ($env:USERPROFILE + "\Documents\accts.csv")
}
process
{
If($All)
{
$vn = $csv.VariableName
}
ForEach($vn in $VariableName)
{
$cred=$null
$cred = Get-Credential -Message ("Enter new credentials for variable named: " + $vn)
If($Cred)
{
$csv = $csv | Where-Object VariableName -ne $vn | Export-Csv ($env:USERPROFILE + "\Documents\accts.csv") -Force
Add-ITDCredentialToCsv -VariableName $vn -Credential $cred
}
}
}
end
{
}
}
<#
.SYNOPSIS
Removes old versions of ITD modules
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
+49
View File
@@ -0,0 +1,49 @@
### fill in first three lines with csv path and distribution group names
$Import = Import-Csv 'D:\Downloads\nd-all-managers.csv' -Header DeptNum,CAPSUPN,UPN,Name,Cabinet
$AllStateGroupName = ''
$CabinetGroupName = ''
$AllStateGroup = Get-DistributionGroup -Identity $AllStateGroupName
$AllStateGroupMembers = $AllStateGroup | Get-DistributionGroupMember
$CabinetGroup = Get-DistributionGroup -Identity $CabinetGroupName
$CabinetGroupMembers = $CabinetGroup | Get-DistributionGroupMember
$CompareAllState = Compare-Object -ReferenceObject $Import -DifferenceObject $AllStateGroupMembers -IncludeEqual
# <= Add to Group
# == No change
# => Remove from group
$AllStateUsersToAdd = $Compare | Where-Object SideIndicator -eq '<='
$AllStateUsersToRemove = $Compare | Where-Object SideIndicator -eq '=>'
ForEach($User in $AllStateUsersToAdd)
{
Add-DistributionGroupMember -Identity $AllStateGroupName -Member $User
}
ForEach($User in $AllStateUsersToRemove)
{
Remove-DistributionGroupMember -Identity $AllStateGroupName -Member $User
}
$CompareCabinetManagers = Compare-Object -ReferenceObject ($Import | Where-Object Cabinet -eq 'Y') -DifferenceObject $CabinetGroupMembers -IncludeEqual
# <= Add to Group
# == No change
# => Remove from group
$CabinetUsersToAdd = $Compare | Where-Object SideIndicator -eq '<='
$CabinetUsersToRemove = $Compare | Where-Object SideIndicator -eq '=>'
ForEach($User in $CabinetUsersToAdd)
{
Add-DistributionGroupMember -Identity $CabinetGroupName -Member $User
}
ForEach($User in $CabinetUsersToRemove)
{
Remove-DistributionGroupMember -Identity $CabinetGroupName -Member $User
}
+35
View File
@@ -0,0 +1,35 @@
$M365Groups = Get-ADGroup -Filter {Name -like "*-O365-E3"}
#$VPNGroups = Get-ADGroup -Filter {Name -like "*VPN*"}
$UsersToAdd=@()
[int]$TotalUsers=0
ForEach($M365Group in $M365Groups)
{
$user = $null
$users = $null
$Users = Get-ADGroupMember -Identity $M365Group.SamAccountName
$TotalUsers += $Users.count
$AllUsers += $Users
Write-Warning -Message ([string](Get-Date) + " Group: " + $M365Group.SamAccountName)
Write-Warning -Message ([string](Get-Date) + " User count " + $Users.count)
Foreach($User in $Users)
{
$ADUser = Get-ADUser -Identity $User -Properties EmailAddress,Company,Department,CanonicalName
$UserMemberOf = (Get-ADUser -Identity $User -Properties MemberOf).MemberOf | Sort-Object
$UserMemberOfVPN = $UserMemberOf | Where-Object {$_ -like "*VPN*"}
If(@($UserMemberOfVPN).count -eq 0)
{
$UsersToAdd += $ADUser
}
}
Write-Warning -Message ([string](Get-Date) + " UsersToAdd Total count " + $UsersToAdd.count)
}
$UsersToAdd | Export-Csv D:\UsersToAdd.csv
#Add-ADGroupMember -Identity ITD-COVID19-SSLVPN -Members $UsersToAdd -Credential $AdminCred
Add-ADGroupMember -Identity ITD-COVID19-SSLVPN -Members (Import-Csv D:\UsersToAdd-Enabled.csv).SamAccountName -Credential $AdminCred
+10
View File
@@ -0,0 +1,10 @@
# Write your PowerShell commands here.
Write-Host "##vso[task.setvariable variable=Hostname]deploy002"
Write-Host "##vso[task.setvariable variable=IpAddress]192.168.99.99"
Write-Host "##vso[task.setvariable variable=IpAddress]255.255.255.0"
Write-Host "##vso[task.setvariable variable=IpAddress]192.168.99.1"
HPE_Synergy_Composer_2_6.00.00_UPDATE_Z7550-97071.bin
69321351ad32a401ad3cd6f5b1d715a2c984f7c077e57afe7acd3d527a7cc3ce
69321351ad32a401ad3cd6f5b1d715a2c984f7c077e57afe7acd3d527a7cc3ce
+8
View File
@@ -0,0 +1,8 @@
$postParams = [PSCustomObject]@{
AutomationName = "Infra-VMware";
Action = 'Provisioning';
Units = 5;
Platform = 'PowerShell-VMware-SnapshotNew';
}
Invoke-RestMethod -Uri http://itdnettools.nd.gov/services/automation-tracking.py -Method POST -Body ($postParams | ConvertTo-Json)
+30
View File
@@ -0,0 +1,30 @@
$acctkey="m1baKn6kkg5fL/wJzHFrDq28LmDCK0ylVXj9bWCJxW/JwJ6or03Qska4jZPpVAC63Tt19i254pvrY8sqI8iKCA=="
#DefaultEndpointsProtocol=https;AccountName=sazmeiersharedm365;AccountKey=m1baKn6kkg5fL/wJzHFrDq28LmDCK0ylVXj9bWCJxW/JwJ6or03Qska4jZPpVAC63Tt19i254pvrY8sqI8iKCA==;EndpointSuffix=core.windows.net
$storageContext = New-AzureStorageContext -StorageAccountName 'sazmeiersharedm365' -StorageAccountKey $acctkey
$LogFull = "zmtestfile01.log"
$LogItem = New-Item -ItemType File -Name $LogFull -force
Set-AzureStorageBlobContent -File $LogFull -Container "azuretest" -BlobType Block -Context $storageContext -Verbose
$AllTeams = Get-Team
$AllTeams | export-csv "C:\users\zmeier\desktop\filetest03.csv"
Set-AzureStorageBlobContent -File "filetest03.csv" -Container "azuretest" -BlobType Block -Context $storageContext
<# In runbook:
$svcitdm365auto = Get-AutomationPSCredential -Name 'Microsoft365 Auto'
Connect-MicrosoftTeams -Credential $svcitdm365auto
$acctkey = (Get-AutomationPSCredential -Name 'Azure-sazmeiersharedm365').GetNetworkCredential().Password
$storageContext = New-AzureStorageContext -StorageAccountName 'sazmeiersharedm365' -StorageAccountKey $acctkey
#$LogName = "zmtestfile02.log"
#$LogItem = New-Item -ItemType File -Name $LogName
#Set-AzureStorageBlobContent -File $LogName -Container "azuretest" -BlobType Block -Context $storageContext -Verbose
$AllTeams = Get-Team
$AllTeams | export-csv "$env:TEMP\filetest03.csv" -notypeinformation
Set-AzureStorageBlobContent -File "$env:TEMP\filetest03.csv" -Container "azuretest" -BlobType Block -Context $storageContext#>
+22
View File
@@ -0,0 +1,22 @@
$AllWebApps = Get-AzureRMWebApp
$result = @()
ForEach($app in $AllWebApps)
{
$hash = @{
'Name' = $app.Name;
'Location' = $app.Location;
}
$Tags = $app.tags
ForEach($TagKey in $Tags.Keys)
{
$hash += @{$TagKey = $Tags.$TagKey}
}
$obj = New-Object -TypeName psobject -Property $hash
$result += $obj
}
$result
+90
View File
@@ -0,0 +1,90 @@
$Subscriptions = Get-AzSubscription
$AzureVMs = [System.Collections.ArrayList]@()
ForEach ($Subscription in $Subscriptions) {
Set-AzContext -Subscription $Subscription
$AllVMs = Get-AzVM
ForEach ($VM in $AllVMs) {
$VMSize = $null
$VMSizeSpecs = $null
$OSDisk = $null
$DataDisks = $null
$obj = $null
$VMSize = $VM.HardwareProfile.VMSize
$VMSizeSpecs = Get-AzVMSize -Location $VM.Location | Where-Object { $_.Name -eq $VMSize }
$OSDisk = $VM.StorageProfile.OSDisk
$DataDisks = $VM.StorageProfile.DataDisks
#$IpAddress = (Get-AzNetworkInterface | Where-Object {$_.Id -eq $VM.NetworkProfile.NetworkInterfaces.Id}).IpConfigurations.PrivateIpAddress
$obj = [PSCustomObject]@{
VMName = $VM.Name
Subscription = $Subscription.Name
ComputerName = $VM.OSProfile.ComputerName
Size = $VMSize
CPU = $VMSizeSpecs.NumberOfCores
Memory = ($VMSizeSpecs.MemoryInMb / 1024)
TotalDisk = ($OSDisk.DiskSizeGB + ($DataDisks.DiskSizeGB | Measure-Object -Sum).Sum)
OsDiskGB = $OSDisk.DiskSizeGB
DataDisksGB = $DataDisks.DiskSizeGB -join ", "
}
$null = $AzureVMs.Add($obj)
}
}
$SharePointList = Get-ITDVMwareSharePointVMGuestList | Where-Object { $_.Status -notlike "D*" -and ($_.DataCenter -like "MAC*" -or $_.DataCenter -like "MAG*") }
$AzureToSharePointCompare = [System.Collections.ArrayList]@()
ForEach ($AzVM in $AzureVMs) {
$SPItem = $null
Write-Verbose -Message ("Start " + $AzVM.VMName) -Verbose
$SPItem = $SharePointList | Where-Object { $_.Title -match $AzVM.VMName.split('-')[1] }
Write-Verbose -Message ("Found " + $SPItem.Count + " possible SharePoint matches") -Verbose
$obj = [PSCustomObject]@{
AzVMName = $AzVM.VMName;
#AzComputerName = $AzVM.ComputerName
SPTitle = $SPItem.Title;
CPU = $null;
MemoryGB = $null;
DiskTotal = $null;
}
Write-Verbose -Message "One match found, starting compare"
If ($SPItem.Processors -ne $AzVM.CPU) {
$obj.CPU = $false
}
Else {
$obj.CPU = $true
}
If ($SPItem.RAM -ne $AzVM.Memory) {
$obj.MemoryGB = $false
}
Else {
$obj.MemoryGB = $true
}
$SPDiskTotalGB = $SPItem.Disk1 + $SPItem.Disk2 + $SPItem.Disk3 + $SPItem.Disk4
If ($SPDiskTotalGB -ne $AzVM.TotalDisk) {
$obj.DiskTotal = $false
}
Else {
$obj.DiskTotal = $true
}
$null = $AzureToSharePointCompare.Add($obj)
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

+14
View File
@@ -0,0 +1,14 @@
for node in 01 02 03 04 05 06 07 08 09 10
do ssh -i ~cecogdill/.ssh/id_rsa_itdmdndpc01 support@itdmdndpc01n$node.nd.gov "sudo timeout 180 tcpdump -C 200 -i br0.3895 -s 65535 -w pcap.out '(src net 10.2.170.0/24 or src net 10.2.169.128/26)' and '(dst net 10.2.169.128/26 or dst net 10.2.170.0/24)' and src net not 10.29.0.0/23 and port not 22 &"
done
for node in 01 02 03 04 05 06 07 08 09 10
do ssh -i ~cecogdill/.ssh/id_rsa_itdmdndpc01 support@itdmdndpc01n$node.nd.gov "sudo pkill timeout"
done
for host in `ls`; do cd $host; ssh -i ~cecogdill/.ssh/id_rsa_itdmdndpc01 support@$host.nd.gov 'rm pcap.out*'; done
+25
View File
@@ -0,0 +1,25 @@
$AllVMs = Get-VM | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
#$DataProtectionVMs = (Get-TagAssignment -Category DataProtection).Entity | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
$result = [System.Collections.ArrayList]@()
ForEach ($VM in $AllVMs) {
$AppName = ($VM | Get-TagAssignment -Category AppName).Tag.Name;
$CohesityGB = (($VM | Get-harddisk) | Measure-object -sum CapacityGB).sum;
#$AppTotalGB = ($AllVMs | Get-TagAssignment -Category AppName | Where-object Name -eq $AppName);
$OldTag = ($VM | Get-TagAssignment -Category DataProtection).Tag.Name
$vCenter = $VM.Uid.split('@').split(':')[1]
$obj = [PSCustomObject]@{
'Name' = $VM.Name;
'AppName' = $AppName;
'CohesityGB' = $CohesityGB
'OldTag' = $OldTag;
'vCenter' = $vCenter;
}
#Write-Output $obj
$null = $result.Add($obj)
}
$group = $result | group-object AppName | select Count,Name,@{n='CohesityGB';e={($_.Group | measure-object -sum CohesityGB).sum}}#,@{n='NotCohesityGB';e={}}
#Get-Tag -Category AppName -Name DHS-SPACES
+47
View File
@@ -0,0 +1,47 @@
$AppNamesWithSQL=@"
BND-APCheck
BND-Fiserv
BND-FUNDTECH
BND-Reporting
BND-SQL
CJIS-Justware-SQL
CJIS-LERMS-SQL
DEQ-nVIRO
DES-CAD
DHS-Avatar-SQL
DHS-MMIS-MoveIT
DHS-MMIS-Truven-Windows
DHS-MMIS-Xpressions-SQL
DHS-Pyxis
DHS-VISION
DOH-WIC
DOT-GIS
DOT-HEAT-SQL
DOT-RoadTest
DOT-STARS
HPN-Video
Infra-Desktop-SCCM-SQL
Infra-Passwordstate
Infra-Security-Investigation
Infra-Security-MFA-SafeNet
Infra-Security-MFA-SafeNet-SQL
Infra-Servers-SCCM-SQL
ITD-EDUTec-K12FIM-SQL
ITD-POC-Desktop
ITD-SLDS
ITD-SLDS-EDFI-ODS
JSN-EAE
RRI-Macola
Shared-PeopleSoft-HigherEd
Shared-PeopleSoft-State
Shared-SharePoint-SQL
Shared-SQL
Shared-SQL-DR
SOS-BPRO-SQL
SOS-CentralIndexing
TAX-GenTax
WSI-Extranet-SQL
WSI-Reporting
"@
$AppNamesWithSQL = ConvertTo-Array -MultiLineString $AppNamesWithSQL
@@ -0,0 +1,82 @@
$AllCohesityProtectionGroups = Get-CohesityProtectionJob | Where-Object Environment -eq kVMware | sort-object Name
$AllCohesityVMwareVM = Get-CohesityVMwareVM
$toDisable=@()
ForEach($ProtectionJob in $AllCohesityProtectionGroups){
$IncludeTags = $ProtectionJob.vmTagIds[0][0]
If($ProtectionJob.excludeVmTagIds[0][0]){
$ExcludeTags = $ProtectionJob.excludeVmTagIds[0][0]
}
$IncludeVMs = $AllCohesityVMwareVM | where-object {$_.VmWareProtectionSource.TagAttributes.Id -eq $IncludeTags} | Sort-object Name
If($ProtectionJob.excludeVmTagIds[0][0]){
$ExcludeVMs = $AllCohesityVMwareVM | where-object {$_.VmWareProtectionSource.TagAttributes.Id -eq $IncludeTags -and $_.VmWareProtectionSource.TagAttributes.Id -eq $ExcludeTags} | Sort-object Name
}
Else{
$ExcludeVMs = $null
}
$VMsToBackup = $IncludeVMs | where-object {$ExcludeVMs -notcontains $_}
If(@($VMsToBackup).count -ge 1){
# enable protection job
#$ProtectionJob.isPaused = $False
#$ProtectionJob | Set-CohesityProtectionJob -Confirm:$false
}
Else{
# disable protection job
#$ProtectionJob.isPaused = $True
#$ProtectionJob | Set-CohesityProtectionJob -Confirm:$false
$toDisable += $ProtectionJob
}
}
<#
"tagAttributes": [
{
"gcpTagType": null,
"id": 8334,
"name": "Reserved",
"uuid": "urn:vmomi:InventoryServiceTag:7ec35aab-9234-4324-93c3-695e5664ed74:GLOBAL"
},
{
"gcpTagType": null,
"id": 3407,
"name": "Shared-PowerSchool",
"uuid": "urn:vmomi:InventoryServiceTag:996627f1-ee30-4d92-8249-b1aa71c63d75:GLOBAL"
},
{
"gcpTagType": null,
"id": 7065,
"name": "Windows Server 2012 R2 Standard (64-Bit)",
"uuid": "urn:vmomi:InventoryServiceTag:89e77b90-2876-476d-a346-2c9da6583ce9:GLOBAL"
},
{
"gcpTagType": null,
"id": 3223,
"name": "ABR",
"uuid": "urn:vmomi:InventoryServiceTag:31bda67f-a610-460c-bd7c-75cc1adeb4c6:GLOBAL"
},
{
"gcpTagType": null,
"id": 3205,
"name": "4",
"uuid": "urn:vmomi:InventoryServiceTag:3fd9b786-5d50-42b1-912e-95b9f0262891:GLOBAL"
},
{
"gcpTagType": null,
"id": 3225,
"name": "Production",
"uuid": "urn:vmomi:InventoryServiceTag:3d04149e-c1aa-4f46-a7f5-f0cfcb1b4414:GLOBAL"
},
{
"gcpTagType": null,
"id": 7108,
"name": "No Licensing Restrictions",
"uuid": "urn:vmomi:InventoryServiceTag:049ee6ff-5205-4b2c-bc20-a0c44e2eb05c:GLOBAL"
}
#>
+119
View File
@@ -0,0 +1,119 @@
$Filter = '&$select=ID,Title,DateCreated,Status,DataCenter,Environment,StartupPriority,OS,Processors,RAM,DiskTotal,DataProtection,DR_Protection,SRM_RecoveryVMtype,LicensingRestrictions,Network/Vlan_Id,Network/CIDR,AppName/Title,Cluster/Name&$expand=Network/Id,AppName/Id,Cluster/Id'
$URLVMItems = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VM Guests')/items?" + '$top=10000' + $Filter
$InvokeRestMethodParams = @{
Uri = $URLVMItems;
Method = "Get";
headers = @{ "Accept" = "application/json;odata=verbose" };
UseBasicParsing = $true;
}
$z = (Invoke-RestMethod @InvokeRestMethodParams -UseDefaultCredentials) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
$VMList = $z.d.results
$URLAppNames = "https://share.nd.gov/itd/computer-systems/distributed-systems/vmware/_api/lists/getbytitle('VM App Name')/items?" + '$top=10000'
$InvokeRestMethodParams = @{
Uri = $URLAppNames;
Method = "Get";
headers = @{ "Accept" = "application/json;odata=verbose" };
UseBasicParsing = $true;
}
$z = (Invoke-RestMethod @InvokeRestMethodParams -UseDefaultCredentials) -creplace '"Id":', '"Idx":' | ConvertFrom-Json
$AppNameList = $z.d.results
$AllAppNameVMs = $AppNameList | where-object Cohesity -eq "All VMs"
$NewAppNameVMs = $AppNameList | where-object Cohesity -eq "New VMs Only"
# compare new vm list to cohesity vm list
$NewVMs = $VMList | where-object DateCreated -gt (Get-Date -Year 2021 -Month 2 -Day 1)
$CohesityVMs = Get-CohesityVMwareVM -Protected
$compare = Compare-Object -ReferenceObject $NewVMs.Title -DifferenceObject $CohesityVMs.Name
$VMsToAdd = $compare | where-object Sideindicator -eq "<="
$VMsToAddAppNames = $VMsToAdd.InputObject | forEach-object { ($VMList | where-object Title -eq $_).AppName.Title } | Select-Object -unique
$AllProtectionGroups = Get-CohesityProtectionJob
$AllProtectionSourceObject = Get-CohesityProtectionSourceObject
$AppNamesToReview = [System.Collections.ArrayList]@()
ForEach ($AppName in $VMsToAddAppNames) {
$SourceObjects = $AllProtectionSourceObject | Where-Object Name -eq $AppName
$ExistingPGs = Get-CohesityProtectionJob -Names $AppName
If ($ExistingPGs) {
$PGsWithTags = $ExistingPGs | where-object { $_.vmTagIds -match '8744' -or $_.vmTagIds -match '8747' }
If ($PGsWithTags) { $Style = "Tagged VMs" }
Else { $Style = "All VMs" }
$obj = [PSCustomObject]@{
AppName = $AppName;
Style = $Style
}
}
Else {
$obj = [PSCustomObject]@{
AppName = $AppName;
Style = "New PG, needs human"
}
}
$null = $AppNamesToReview.Add($obj)
}
$AppNamesToReview | sort-object AppName
ForEach ($item in $VMsToAdd) {
$SPItem = $null
# get appname, then appname metadata
$VMSPItem = $VMList | where-object Title -eq $item.InputObject
$AppName = $VMSPItem.AppName.Title
$AppNameSPItem = $AppNameList | where-object Title -eq $AppName
ForEach ($SourceObject in $SourceObjects) {
switch ($AppNameSPItem.Cohesity) {
$null {
If ($AppNameSPItem.Created -gt (Get-Date -Year 2021 -Month 2 -Day 1)) {
# created after 2021-02-01, set "All VMs"
$AppNameProtection = "All VMs"
}
Else {
# created before 2021-02-01, set "New VMs"
$AppNameProtection = "New VMs Only"
}
}
}
}
# find if protection group exists
$CohesityPGs = Get-CohesityProtectionJob -Names $AppName
If ($CohesityPGs) {
}
Else {
New-ITDCohesityProtectionGroupWIP -AppName $AppName
switch ($AppNameProtection) {
'All VMs' {
# do nothing
}
'New VMs Only' {
}
}
}
# create protection group if needed, configure for "All VMs" condition, end
# if protection group exists, find out if protect all VMs, or just new
# if all VMs, no work to do
# if new VMs, add VM to protection group
}
# Cohesity Protection Groups with the entire AppName protected
Get-CohesityProtectionJob | Where-Object { $_.vmTagIds -notmatch 8747 -and $_.vmTagIds -notmatch 8744 } | sort-object Name
# Cohesity Protection Groups with only new AppName VMs protected
Get-CohesityProtectionJob | Where-Object { $_.vmTagIds -match 8747 -or $_.vmTagIds -match 8744 } | sort-object Name
+29
View File
@@ -0,0 +1,29 @@
# list
$ProtectionGroups = Get-CohesityProtectionJob | where-object environment -eq kVMware | sort-object Name
$ProtectionGroups | Select-Object name, @{n = 'AllowPrefixes'; e = { $_.indexingpolicy.allowprefixes } }, @{n = 'DenyPrefixes'; e = { $_.indexingpolicy.denyprefixes } } | sort-object Name
<#ignore
program files x2
var
#>
$indexingPolicy = [PSCustomObject]@{
disableIndexing = $false;
allowPrefixes = @('/');
denyPrefixes = @('/$Recycle.Bin','/Windows','/ProgramData','/System Volume Information','/Users/*/AppData','/Recovery','/usr','/sys','/proc','/lib','/grub','/grub2','opt/splunk','/splunk')
}
#$ProtectionJob = Get-CohesityProtectionJob -Names "DOH-StarLIMS@itdvmvc1"
$ProtectionGroups = Get-CohesityProtectionJob | where-object environment -eq kVMware | sort-object Name
ForEach ($ProtectionJob in $ProtectionGroups) {
If($ProtectionJob.indexingPolicy){
$ProtectionJob.indexingPolicy = $indexingPolicy
}
Else
{
$ProtectionJob | Add-Member -MemberType NoteProperty -Name indexingPolicy -Value $indexingPolicy
}
Set-CohesityProtectionJob -ProtectionJob $ProtectionJob -Confirm:$false
}
+25
View File
@@ -0,0 +1,25 @@
$func = {
#Add to Local Security Policy
function Add-ServiceLogonRight([string] $Username) {
Write-Host "Enable ServiceLogonRight for $Username"
$tmp = New-TemporaryFile
secedit /export /cfg "$tmp.inf" | Out-Null
(Get-Content -Encoding ascii "$tmp.inf") -replace '^SeServiceLogonRight .+', "`$0,$Username" | sc -Encoding ascii "$tmp.inf"
secedit /import /cfg "$tmp.inf" /db "$tmp.sdb" | Out-Null
secedit /configure /db "$tmp.sdb" /cfg "$tmp.inf" | Out-Null
Remove-Item $tmp* -ea 0
}
Add-ServiceLogonRight -Username svccohesityadm
# Set Service to Run as Service Account
Stop-Service -Name CohesityAgent
sc.exe config "CohesityAgent" obj="NDGOV\svccohesityadm" password="memo-fUpHMMgXnv"
Start-Service -Name CohesityAgent
# Add to Local Administrators group
Add-LocalGroupMember -Group Administrators -Member "ndgov\svccohesityadm"
}
Invoke-Command -ComputerName itddhssql19p1.nd.gov -Credential $PrvCred -ScriptBlock $func
+21
View File
@@ -0,0 +1,21 @@
#Add to Local Security Policy
function Add-ServiceLogonRight([string] $Username) {
Write-Host "Enable ServiceLogonRight for $Username"
$tmp = New-TemporaryFile
secedit /export /cfg "$tmp.inf" | Out-Null
(Get-Content -Encoding ascii "$tmp.inf") -replace '^SeServiceLogonRight .+', "`$0,$Username" | sc -Encoding ascii "$tmp.inf"
secedit /import /cfg "$tmp.inf" /db "$tmp.sdb" | Out-Null
secedit /configure /db "$tmp.sdb" /cfg "$tmp.inf" | Out-Null
Remove-Item $tmp* -ea 0
}
Add-ServiceLogonRight -Username svccohesitysql
# Set Service to Run as Service Account
Stop-Service -Name CohesityAgent
sc.exe config "CohesityAgent" obj="NDGOV\svccohesitysql" password="radiant-yx8aHMrGtc"
Start-Service -Name CohesityAgent
# Add to Local Administrators group
Add-LocalGroupMember -Group Administrators -Member "ndgov\svccohesitysql"
+28
View File
@@ -0,0 +1,28 @@
$ProtectionJob = Get-CohesityProtectionJob -Names "ZM-Performance Test Bismarck"
$VMwareVM = Get-CohesityVMwareVM -Protected -Names itdvmutil.nd.gov
$ProtectionSourceObject = Get-CohesityProtectionSourceObject -Environments KVMware | Where-Object Name -eq "itdvmutil.nd.gov"
# 4312
# 3156
# 4584
# 3156
Restore-CohesityFile -TaskName "zmRestoreFileTest" `
-FileNames /D/Upgrades/VMware/old/VMware-VCSA-all-6.5.0U3g-14836121.iso `
-JobId $ProtectionJob.Id `
-SourceId ($ProtectionSourceObject | Select -Unique ParentId).ParentId `
-TargetSourceId $VMwareVM.Id `
-TargetParentSourceId $VMwareVM.ParentId `
-TargetHostType KWindows `
-TargetHostCredential (Get-Credential)
Restore-CohesityFile -TaskName "restore-file-vm" `
-FileNames /C/data/file.txt `
-JobId 1234 `
-SourceId 843 `
-TargetSourceId 856 `
-TargetParentSourceId 828 `
-TargetHostType KWindows `
-TargetHostCredential (Get-Credential)
+6
View File
@@ -0,0 +1,6 @@
$AdminCred = Get-Credential # run once console session
$PSSession = New-PSSsession -ComputerName itddeqappt1.nd.gov -Credential $AdminCred
Copy-Item -Path C:\localpath.txt -ToSession $PSSession -Destination C:\
Copy-Item -Path C:\remotepath.txt -FromSession $PSSession -Destination C:\
+82
View File
@@ -0,0 +1,82 @@
#MAK & ESU remediation v3.1
$OS = (Get-WMIObject Win32_OperatingSystem).Caption
write-verbose $OS
switch ($OS) {
'Microsoft Windows Server 2008 R2 Datacenter ' {
write-verbose "switch datacenter edition"
$MakId = '4ae528f4-05c3-446e-90ea-a4fbd460b83a'
$MakKey = '33YCD-89CD2-RMYVW-RGX7W-R9XRM'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd' #activationid
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft Windows Server 2008 R2 Enterprise ' {
write-verbose "switch enterprise edition"
$MakId = '6a4bd364-4b60-4856-a727-efb59d94348e'
$MakKey = 'TB9WQ-WKHVH-W7946-WJTVV-Y6QDD'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft Windows Server 2008 R2 Standard ' {
write-verbose "switch standard edition"
$MakId = ''
$MakKey = 'TB9WQ-WKHVH-W7946-WJTVV-Y6QDD'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft Windows 7 Enterprise ' {
write-verbose "switch Win7 enterprise edition"
$MakId = '9abf5984-9c16-46f2-ad1e-7fe15931a8dd'
$MakKey = 'PRV3H-98HJK-6KKBF-RHYTM-JWCRV'
$Esu1Id = '77db037b-95c3-48d7-a3ab-a9c6d41093e0'
$Esu1Key = 'MJCJ8-24DFX-VGK6H-XYBQ7-F6PR8'
$Esu2Id = '0e00c25d-8795-4fb7-9572-3803d91b6880'
$Esu2Key = 'WX34W-WG8MH-TWWCV-PXK96-RDMTJ'
$Esu3Id = '4220f546-f522-46df-8202-4d07afd26454'
$Esu3Key = 'TF336-89RVD-X2FJJ-YV3KF-Q6KPF'
}
'Microsoft® Windows Server® 2008 Standard ' {
write-verbose "switch 08 Standard"
$MakId = 'ad2542d4-9154-4c6d-8a44-30f11ee96989'
$MakKey = 'GQK9D-CT4WQ-9KJ87-FKMT8-MR73Q'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft® Windows Server® 2008 Enterprise ' {
write-verbose "switch 08 Enterprise"
$MakId = 'bb1d27c4-959d-4f82-b0fd-c02a7be54732'
$MakKey = 'GQK9D-CT4WQ-9KJ87-FKMT8-MR73Q'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
}
#cscript C:\Windows\System32\slmgr.vbs -ipk $MakKey
#cscript C:\Windows\System32\slmgr.vbs -ato $MakId
cscript C:\Windows\System32\slmgr.vbs -ipk $Esu1Key
cscript C:\Windows\System32\slmgr.vbs -ato $Esu1Id
cscript C:\Windows\System32\slmgr.vbs -ipk $Esu2Key
cscript C:\Windows\System32\slmgr.vbs -ato $Esu2Id
cscript C:\Windows\System32\slmgr.vbs -ipk $Esu3Key
cscript C:\Windows\System32\slmgr.vbs -ato $Esu3Id
+126
View File
@@ -0,0 +1,126 @@
$servers = @"
itdcjissqlt1.nd.gov
itddlmacpt1.nd.gov
itddlmdev1.nd.gov
itddlmsit1.nd.gov
itddlmtrng1.nd.gov
itddlmuat1.nd.gov
itdnett1.nd.gov
itdombnett1.nd.gov
"@
$servers = ConvertTo-Array -MultiLineString $servers
Invoke-Command -ComputerName $servers -Credential $AdminCred -scriptblock {Get-Process ccmexec,ccmsetup -ErrorAction SilentlyContinue}
# validation
$ESUbool = $false
$KMSbool = $false
$OS = (Get-WMIObject Win32_OperatingSystem).Caption
write-verbose $OS
switch ($OS) {
'Microsoft Windows Server 2008 R2 Datacenter ' {
write-verbose "switch datacenter edition"
$KMSId = '7482e61b-c589-4b7f-8ecc-46d455ac3b87'
$KMSClientKey = '74YFP-3QFB3-KQT8W-PMXWJ-7M648'
$ESUId = '553673ed-6ddf-419c-a153-b760283472fd'
}
'Microsoft Windows Server 2008 R2 Enterprise ' {
write-verbose "switch enterprise edition"
$KMSId = '620e2b3d-09e7-42fd-802a-17a13652fe7a'
$KMSClientKey = '489J6-VHDMP-X63PK-3K798-CPX3Y'
$ESUId = '553673ed-6ddf-419c-a153-b760283472fd'
}
'Microsoft Windows Server 2008 R2 Standard ' {
write-verbose "switch standard edition"
$KMSId = ''
$KMSClientKey = 'YC6KT-GKW9T-YTKYR-T4X34-R7VHC'
$ESUId = '553673ed-6ddf-419c-a153-b760283472fd'
}
'Microsoft Windows 7 Enterprise '{
write-verbose "switch Win7 enterprise edition"
$KMSId = 'ae2ee509-1b34-41c0-acb7-6d4650168915'
$KMSClientKey = 'YC6KT-GKW9T-YTKYR-T4X34-R7VHC'
$ESUId = '77db037b-95c3-48d7-a3ab-a9c6d41093e0'
}
'Microsoft® Windows Server® 2008 Standard '{
write-verbose "switch Win7 enterprise edition"
$KMSId = 'ad2542d4-9154-4c6d-8a44-30f11ee96989'
$KMSClientKey = 'TM24T-X9RMF-VWXK6-X8JC9-BFGM2'
$ESUId = '553673ed-6ddf-419c-a153-b760283472fd'
}
}
$software = Get-WMIObject -Class SoftwareLicensingProduct
$ESUYear1 = $software | Where-Object { $_.Id -eq $ESUId }
If ($ESUYear1) {
If ($ESUYear1.LicenseStatus -eq '1') {
$ESUbool = $true
}
}
$KMS = $software | where-object { $_.Id -eq $KMSId }
If ($KMS) {
If ($KMS.LicenseStatus -eq 1) {
$KMSbool = $true
}
}
If ($ESUbool -eq $true -and $KMSbool -eq $true) {
$compliant = $true
}
else {
$compliant = $false
}
$compliant
#remediation
$OS = (Get-WMIObject Win32_OperatingSystem).Caption
switch ($OS) {
'Microsoft Windows Server 2008 R2 Datacenter ' {
write-verbose "switch datacenter edition"
$KMSId = '7482e61b-c589-4b7f-8ecc-46d455ac3b87'
$KMSClientKey = '74YFP-3QFB3-KQT8W-PMXWJ-7M648'
$ESUKey = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$ESUId = '553673ed-6ddf-419c-a153-b760283472fd'
}
'Microsoft Windows Server 2008 R2 Enterprise ' {
write-verbose "switch enterprise edition"
$KMSId = ''
$KMSClientKey = '489J6-VHDMP-X63PK-3K798-CPX3Y'
$ESUKey = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$ESUId = '553673ed-6ddf-419c-a153-b760283472fd'
}
'Microsoft Windows Server 2008 R2 Standard ' {
write-verbose "switch standard edition"
$KMSId = ''
$KMSClientKey = 'YC6KT-GKW9T-YTKYR-T4X34-R7VHC'
$ESUKey = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$ESUId = '553673ed-6ddf-419c-a153-b760283472fd'
}
'Microsoft Windows 7 Enterprise ' {
write-verbose "switch Win7 Enterprise"
$KMSId = 'ae2ee509-1b34-41c0-acb7-6d4650168915'
$KMSClientKey = '33PXH-7Y6KF-2VJC9-XBBR8-HVTHH'
$ESUKey = 'MJCJ8-24DFX-VGK6H-XYBQ7-F6PR8'
$ESUId = '77db037b-95c3-48d7-a3ab-a9c6d41093e0'
}
'Microsoft® Windows Server® 2008 Standard '{
write-verbose "switch Win7 enterprise edition"
$KMSId = 'ad2542d4-9154-4c6d-8a44-30f11ee96989'
$KMSClientKey = 'TM24T-X9RMF-VWXK6-X8JC9-BFGM2'
$ESUKey = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$ESUId = '553673ed-6ddf-419c-a153-b760283472fd'
}
}
cscript C:\Windows\System32\slmgr.vbs -ipk $KMSClientKey
cscript C:\Windows\System32\slmgr.vbs -skms itdkms2.nd.gov
cscript C:\Windows\System32\slmgr.vbs -ato $KMSId
cscript C:\Windows\System32\slmgr.vbs -ipk $ESUKey
cscript C:\Windows\System32\slmgr.vbs -ato $ESUId
cscript C:\windows\system32\slmgr.vbs /dlv
+85
View File
@@ -0,0 +1,85 @@
$servers=@"
bnd0424.bnd.nd.gov
bnd0425.bnd.nd.gov
bnd0426.bnd.nd.gov
bnd0427.bnd.nd.gov
bnd0430.bnd.nd.gov
bnd0431.bnd.nd.gov
bnd0432.bnd.nd.gov
bnd0433.bnd.nd.gov
bnd0434.bnd.nd.gov
bnd0436.bnd.nd.gov
bnd0437.bnd.nd.gov
bnd0555.nd.gov
bnd0559.nd.gov
bnd0560.nd.gov
bnd0655.nd.gov
bnd0656.nd.gov
bndapp12.bnd.nd.gov
descadlive.nd.gov
descadtrain.nd.gov
dhssosrvlnapp.itd.nd.gov
dhssosrvlnhub.itd.nd.gov
itdapp7.itd.nd.gov
itdapp8.nd.gov
itdcjissqlp1.nd.gov
itdcjissqlrep1.nd.gov
itdcjissqlt1.nd.gov
itdcogmmisprm.prm.mmis.nd.gov
itdcogmmisprm2.prm.mmis.nd.gov
itdcogmmissit.sit.mmis.nd.gov
itdcogmmistrn.trn.mmis.nd.gov
itdcogmmisuat.uat.mmis.nd.gov
itddhsmmisjhd.nd.gov
itddlmacpt1.nd.gov
itddlmdev1.nd.gov
itddlmprtprod.nd.gov
itddlmsit1.nd.gov
itddlmtrng1.nd.gov
itddlmuat1.nd.gov
itddocemrrdp1.nd.gov
itddohvid.itd.nd.gov
itddotgisweb.nd.gov
itdgeolynx2.itd.nd.gov
itdgnfcody2.nd.gov
itdmciwkbench.itd.nd.gov
itdmfa1.nd.gov
itdmfa2.nd.gov
itdmfa3.nd.gov
itdmfasql1.nd.gov
itdmfasql2.nd.gov
itdmmistmart.nd.gov
itdnaom1.itd.nd.gov
itdnet35p1.itd.nd.gov
itdnet35p2.itd.nd.gov
itdnet35t1.itd.nd.gov
itdnet35t2.itd.nd.gov
itdnetp1.itd.nd.gov
itdnett1.itd.nd.gov
itdombnetp1.nd.gov
itdombnett1.nd.gov
itdopenscan1.itd.nd.gov
itdopenscan1tst.itd.nd.gov
itdopenscan2.itd.nd.gov
itdprmxpr4.mmis.nd.gov
itdprmxprsql1.mmis.nd.gov
itdratrpt1.mmis.nd.gov
itdratrpt2.mmis.nd.gov
itdratrpt3.mmis.nd.gov
itdratrpt4.mmis.nd.gov
itdratrpt5.mmis.nd.gov
itdsitxpr4.mmis.nd.gov
itduatxpr4.mmis.nd.gov
itdwsiitsm.nd.gov
nodak00.itd.nd.gov
nodak02.itd.nd.gov
nodak04.itd.nd.gov
wsiapp1.itd.nd.gov
ITDDOTFRSQL1.nd.gov
ITDDOTFRWeb1.nd.gov
ITDDOTFRAPP1.nd.gov
"@
$servers = ConvertTo-Array -MultiLineString $servers
$result = $servers | ForEach-Object -Parallel {resolve-dnsname $_ | select Name,IPAddress}
+21
View File
@@ -0,0 +1,21 @@
$Datastores = Get-Datastore *224*, *225*, *226*
$Folders = @()
ForEach ($Datastore in $Datastores) {
$DatastoreName = $Datastore.Name
$Folders += Get-ChildItem "vmstores:\itdvmvc2.nd.gov@443\Secondary Datacenter\$DatastoreName" | where-object { $_.ItemType -eq "Folder" -and $_.Name -ne '.dvsData' -and $_.Name -ne '.sdd.sf' -and $_.Name -ne '.vSphere-HA' }
}
$result = @()
ForEach ($Folder in $Folders) {
$obj = [PSCustomObject]@{
Datastore = $Folder.PSPath.split('\')[-2];
Folder = $Folder.Name;
SizeGB = [math]::Round(((Get-ChildItem -Path $Folder.FullName) | Measure-Object -Property Length -Sum).Sum / 1GB, 2);
}
$result += $obj
}
$VMs = Get-VM $Folders.Name | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" } -ErrorAction SilentlyContinue | sort-object Name
Compare-Object $Folders.Name $VMs.Name | sort-object InputObject
F
+12
View File
@@ -0,0 +1,12 @@
$x=(Invoke-WebRequest -Uri 'https://api.darksky.net/forecast/974eb758cd9ed981450e20a6ebd9427d/46.849925,-100.781303').content | convertfrom-json
"1575065880"
[DateTimeOffset]::FromUnixTimeSeconds(1575064339)
(Invoke-RestMethod -uri 'https://api.darksky.net/forecast/974eb758cd9ed981450e20a6ebd9427d/46.849925,-100.781303').Content | clip
((Invoke-WebRequest -Uri 'https://api.darksky.net/forecast/974eb758cd9ed981450e20a6ebd9427d/46.849925,-100.781303').content | convertfrom-json).currently
+74
View File
@@ -0,0 +1,74 @@
# confirmed working on DL380 Gen10 with HPEiLOCmdlets version 3.2.0.0
# 2024/02/05 -- still requires PowerShell 5.1 "for some reason"
### #####itdvmmdnwin11lo.nd.gov
#$iLOCred = Get-Secret -Name IloSboxCred
Import-Module HPEiLOCmdlets
$iLOCred = Get-Credential
$iLOFQDNs = @"
itdvmbisps16lo.nd.gov
itdvmbiswas09lo.nd.gov
"@
<#
#>
$iLOFQDNs = ConvertTo-Array -MultiLineString $iLOFQDNs
$iLOConnections = ForEach ($iLOFQDN in $iLOFQDNs) {
Connect-HPEiLO -Address $iLOFQDN -Credential $iLOCred -DisableCertificateAuthentication
}
Get-HPEiLOSSLCertificateInfo -Connection $iLOConnections -ov x
ForEach ($iLOConnection in $iLOConnections) {
Start-HPEiLOCertificateSigningRequest -Connection $iLOConnection `
-CommonName $iloConnection.Hostname `
-Organization "State of North Dakota" `
-Country US `
-City Bismarck `
-State "North Dakota" `
-OrganizationalUnit NDIT
}
Start-Sleep -Seconds 30
#wait 30 seconds, then continue -- will copy CSR to clipboard, paste it into Ansible playbook, vmware@nd.gov for email, hit Enter and loop
ForEach ($iLOConnection in $iLOConnections) {
$CSR = Get-HPEiLOCertificateSigningRequest -Connection $iLOConnection
Write-Warning -Message ("Start " + $CSR.Hostname)
$CSR.CertificateSigningRequest | Set-Clipboard
Pause
}
#### send csr to ca
# get certificate back, updating download folder below as needed
# download the "Certificate only, PEM encoded" cert
ForEach ($iLOFQDN in $iLOFQDNs) {
Write-Warning -Message "Start $iloFQDN"
$cert = Get-ChildItem D:\Downloads | Where-Object { $_.Name -eq ($iLOFQDN.replace(".", "_") + "_cert.cer") } | Get-Content
$connection = $iLOConnections | Where-Object Hostname -EQ $iLOFQDN
Import-HPEiLOCertificate -Certificate ($cert | Out-String) -Connection $connection
Write-Warning -Message "End $iloFQDN"
}
# OneView, refresh server hardware
# validate certificate after 30 seconds / iLO reset
[Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
ForEach ($iloFQDN in $iLOFQDNs) {
$url = ("https://" + $iloFQDN)
$req = [Net.HttpWebRequest]::Create($Url)
$req.GetResponse() | Out-Null
$output = [PSCustomObject]@{
URL = $url
'Cert Start Date' = $req.ServicePoint.Certificate.GetEffectiveDateString()
'Cert End Date' = $req.ServicePoint.Certificate.GetExpirationDateString()
}
$output
}
+3
View File
@@ -0,0 +1,3 @@
New-Item C:\HelloWorld.txt -Force
Set-Content -Path C:\HelloWorld\HelloWorld.txt -Value (Get-Date)
### 1
+57
View File
@@ -0,0 +1,57 @@
$Filter = "(samaccountname=$env:username)"
$RootOU = "dc=nd,dc=gov"
Write-Warning $Filter
$Searcher = New-Object DirectoryServices.DirectorySearcher
$Searcher.Filter = $Filter
$result=$Searcher.FindAll()
$homedir = $result.properties.homedirectory
$homedrive = $result.properties.homedrive
$ScriptPath = $result.properties.scriptpath
If($ScriptPath)
{
$LoginScript = "\\nd.gov\netlogon\$ScriptPath"
Start-Process "cmd.exe" "/c $loginscript" #<< run loginscript
}
If($homedrive)
{
New-PSDrive -Name $homedrive.TrimEnd(':') -PSProvider FileSystem -Root $homedir -Persist
}
# SIG # Begin signature block
# MIIFdgYJKoZIhvcNAQcCoIIFZzCCBWMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUEapmZ+ZgSAHkkFVI1S3u06dz
# OdmgggMOMIIDCjCCAfKgAwIBAgIQVQoeTLrf5bJKxVZKPVHSEzANBgkqhkiG9w0B
# AQUFADAdMRswGQYDVQQDDBJMb2NhbCBDb2RlIFNpZ25pbmcwHhcNMjAwMzI0MTky
# NzA3WhcNMjEwMzI0MTk0NzA3WjAdMRswGQYDVQQDDBJMb2NhbCBDb2RlIFNpZ25p
# bmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDARE6vqPLMQ8HioO0e
# O4ryGzcLqfRh3CERGbhSaG4sWxQMWPZWjuYPiYx4CT6rRezzN5ZZSvDVeKBuXTID
# uS9419zgoY8e+L9PBRLyvjFIHTEFvNcbUeX3KyrOUuxOgcMx2ByrbcLSWd2R0ZKW
# L0unmS79073fz49eH+6ixE8VLf55A7bOJ/q/nfPDr8OEhqaCX/aToAIQHd2AMw9M
# G3wZQLWbxs1Re2icogumo2i1DFoPoTbaSeW7ew4762QonUfETLz793EPGFOnopW+
# i8T5o6KjsP4SFOlooi0KOParXAE/S6NSRHpdIHs4KqSw8J3Y1/x8A0AihasnbBbG
# EaZ9AgMBAAGjRjBEMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD
# AzAdBgNVHQ4EFgQULC0jVuwflxdsAkkw3yKVtsNo01cwDQYJKoZIhvcNAQEFBQAD
# ggEBAG+2XCn7n5Q0sV56xynZ64bLdNy/j/ahMND2Hgk/kXbeDYb56M49CLrJluls
# 5i7tChwDxCp6+y+tQxiXKyEUNGSftB5NUS81ONxfpkTx1utKVzOJEMOGNqH1028N
# gAe4t68/5QohoZq4KR/7ui8bVz6mmzUdO2KVmbFEOX/QBQ7YYnbK0hGGAPBLMAh0
# HhRxA0E0UInDXeBnkiFS6IiFKhNzopF1LbgXdt3ZpvJrZQLH9ewP6rDhutki2h9v
# PAX9CS9GLn6Cm9aDk8j/Im/GT0hulstL+ZxK9y22eshV5MzqXJtgVsQEubr+oGIF
# +RA1SR38yy7Ak9wTOo3lQ0T3vNwxggHSMIIBzgIBATAxMB0xGzAZBgNVBAMMEkxv
# Y2FsIENvZGUgU2lnbmluZwIQVQoeTLrf5bJKxVZKPVHSEzAJBgUrDgMCGgUAoHgw
# GAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGC
# NwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQx
# FgQULf3QJRKYaFejcPxKTejtfpjOZQkwDQYJKoZIhvcNAQEBBQAEggEAaDfNu3W9
# bBvj1GLLQ28eQGgA4W6NZmtP6ph4Agav9bmD+9wRl7yR71Vzn0vvJc2sRxDS9ASG
# l0axrfSEWYszlFwxJbmg76IEtUP7DB2uAqKegMsOW3MFJcm337xypJYkhnAL1Im4
# Lo9MKdaNe3BxsFAXVCwqxxZq2bP0n6wSC9AJdQBL04L3RhReP08NpDS+jr7Ar3xl
# WN8AokBj7So/k1hfXBCWfOcgfSXWoz1Cj/+w+s5T9QWt7KFaOQ0s/UoXfivijQ/a
# 5WOa8CdeB89dpFb/mnnIi55dlt4uazJqEsWjKBzdUUqanCLHD4+z/Dy21oIsgpVE
# DGwOO3jiLSoiWg==
# SIG # End signature block
+1
View File
@@ -0,0 +1 @@
powershell.exe -ExecutionPolicy Unrestricted -File .\HomeDrive.ps1
+37
View File
@@ -0,0 +1,37 @@
try
{
$Filter = "(samaccountname=$env:username)"
$RootOU = "dc=nd,dc=gov"
Write-Warning $Filter
$Searcher = New-Object DirectoryServices.DirectorySearcher
$Searcher.Filter = $Filter
$result=$Searcher.FindAll()
$homedir = $result.properties.homedirectory
$homedrive = $result.properties.homedrive
$ScriptPath = $result.properties.scriptpath
Write-Warning ("HomeDirectory: " + $homedir )
Write-Warning ("HomeDrive: " + $homedrive)
If($homedrive)
{
New-PSDrive -Name $homedrive.TrimEnd(':') -PSProvider FileSystem -Root $homedir -Persist
}
If($ScriptPath)
{
Write-Warning ("ScriptPath: " + $ScriptPath)
$LoginScript = "\\nd.gov\netlogon\$ScriptPath"
Start-Process "cmd.exe" "/c $loginscript" #<< run loginscript
}
}
catch
{
New-Item -Path "$env:userprofile\Desktop\MapDrivesError.txt"
$error | Set-Content .\MapDrivesError.txt
}
Read-Host -Prompt "Press Enter to complete"
+24
View File
@@ -0,0 +1,24 @@
$Filter = "(samaccountname=$env:username)"
$RootOU = "dc=nd,dc=gov"
Write-Warning $Filter
$Searcher = New-Object DirectoryServices.DirectorySearcher
$Searcher.Filter = $Filter
$result=$Searcher.FindAll()
$homedir = $result.properties.homedirectory
$homedrive = $result.properties.homedrive
$ScriptPath = $result.properties.scriptpath
If($ScriptPath)
{
$LoginScript = "\\nd.gov\netlogon\$ScriptPath"
Start-Process "cmd.exe" "/c $loginscript" #<< run loginscript
}
If($homedrive)
{
New-PSDrive -Name $homedrive.TrimEnd(':') -PSProvider FileSystem -Root $homedir -Persist
}
+454
View File
@@ -0,0 +1,454 @@
$IISservers = @"
DHSSOSRVLNAPP
DHSSOSRVLNHUB
DOTSERVER3
ITDANDCONT2
ITDAPP11
ITDAPP12
ITDAPP7
ITDAPP8
ITDAPPSCANENT
ITDAPV
ITDASR1
ITDASR2
ITDAUDIT1
itdbzprod1
ITDCA5
ITDCA6
ITDCC2
ITDCDEWEB
ITDCDEWEB1
ITDCITRIXLIC
ITDCJISNETP1
ITDCJISNETT1
ITDCJISNETT2
ITDCJISSQLP1
ITDCJISSQLT1
ITDCLOUDNET1
ITDCLOUDNETP1
ITDCLOUDNETP2
ITDCLOUDNETP3
ITDCLOUDNETT2
ITDCLOUDNETTRN1
ITDCNDHEBOOKS1
ITDCNDHEFRDP10
ITDCNDHEFRDP6
ITDCNDHEHRDP1
ITDCNDHEHRDP7
ITDCNDHEUPK1
ITDCNDHEURDP1
ITDCNDSTBOOKS1
ITDCNDSTFRDP4
ITDCNDSTFRDP6
ITDCNDSTHQWT
ITDCNDSTHRDP6
ITDCNDSTLRDP6
ITDCNDSTLSCORM1
ITDCNDSTRDP855
ITDCNDSTRRDP6
ITDCNDSTRWP
ITDCNDSTUPK1
ITDCNDSTURDP1
ITDCOG11TST
ITDCOGENTDEV
ITDCOGENTPRD1
ITDCOGENTPRD2
ITDCOGENTPUB
ITDCOGENTTST
ITDCOGMMISPRM
ITDCOGMMISPRM2
ITDCOGMMISSIT
ITDCOGMMISTRN
ITDCOGMMISUAT
ITDCOGNDUS
ITDCOMPLIANCE1
ITDCOMPLIANCE2
ITDCRMP1
ITDCRMP2
ITDDEQAPPP1
ITDDEQAPPT1
ITDDEQNETP1
ITDDEQNETT1
ITDDESNETP1
ITDDESNETT1
ITDDEVOS
ITDDFSP1
itddhsawarepz1
itddhsawaretz1
ITDDHSMIDMZP1
ITDDHSMIDMZT1
ITDDHSMIRRIMGP1
ITDDHSMIRRIMGT1
ITDDHSPYXCCEP1
ITDDHSPYXCCET1
ITDDHSPYXESP1
ITDDHSPYXEST1
ITDDHSQMSP1
ITDDHSQMST1
ITDDLMACPT1
ITDDLMDEV1
ITDDLMPRTPROD
ITDDLMSIT1
ITDDLMTRNG1
ITDDLMUAT1
itddmrdmscnv
itddmrdmspfta
itddmrdmspftw
itddmrdmsprda
itddmrdmsprdw
itddmrdmssit
itddmrdmssta
itddmrdmsstw
itddmrdmstrn
itddmrdmsuat
itddmrdmsuit
itddmrdmsutlb
ITDDOCAPPP1
ITDDOCNETP1
ITDDOCNETT1
ITDDOCRCIPS
ITDDOCRRDS
ITDDOHICP1
ITDDOHIMSP1
ITDDOHIMST1
ITDDOHLEGENDP2
ITDDOHLEGENDP3
ITDDOHLEGENDT2
ITDDOHLEGENDT3
ITDDOHNETP3
ITDDOHNETT3
ITDDOHNETT4
ITDDOHPRSP1
itddohslimst1
ITDDOHVID
ITDDOTAPPT1
ITDDOTATMSQ1
ITDDOTDTIMSP1
ITDDOTDTIMST1
ITDDOTEXTDSAIIS
ITDDOTFCR1
ITDDOTFLEETP1
ITDDOTFLEETT1
ITDDOTFRSQL1
ITDDOTGISWEB
ITDDOTGISWEB2
ITDDOTGISWEB3
ITDDOTHEAT
ITDDOTINTDSAIIS
ITDDOTMVP1
ITDDOTMVP2
ITDDOTMVP3
ITDDOTMVS2
ITDDOTMVS3
ITDDOTNAS3
ITDDOTNETEP1
ITDDOTNETET1
ITDDOTNETP1
ITDDOTNETT1
ITDDOTNETT2
ITDDOTRTP1
ITDDOTRTT1
ITDDOTSCCM12
ITDDOTSERVER4
ITDDOTSTS
ITDDOTTFSP1
itddottrvltmp1
ITDDOTUNI3
ITDDOTUNI4
ITDDPA1
ITDDPINETT1
ITDDPISAARP1
ITDDPISAARP2
ITDDPISAART1
ITDDPISAART2
ITDECAS2
ITDERNSAG1
ITDERNSAG10
ITDERNSAG12
ITDERNSAG13
ITDERNSAG2
ITDERNSAG3
ITDERNSAG4
ITDERNSAG5
ITDERNSAG6
ITDERNSAG7
ITDERNSAG8
ITDERNSAG9
ITDEXCHCASBIS1
ITDEXCHCASMAN1
ITDEXCHMBXBIS1
ITDEXCHMBXBIS2
ITDEXCHMBXMAN1
ITDEXCHMBXMAN2
ITDEXCHT1
ITDEXCHT2
ITDFUSION
ITDGEOLYNX1
ITDGEOLYNX2
ITDGISUTILITY
ITDGNFCODY2
ITDGNFGEO1
ITDHEATDEV1
ITDHEATPROD1
ITDHEATT1
ITDHPNEARP1
ITDHPNEARP2
ITDHPNEARP3
ITDHPNEARP4
ITDHPNEART1
ITDHPNEART2
ITDILAPP1
ITDILAPP1TST
ITDILEF1
ITDILEF1TST
ITDILEM1
ITDILEM1TST
ITDILWEB1
ITDILWEB1TST
ITDILWEB2
ITDILWEB2TST
ITDJSNABSUITEP1
ITDJSNABSUITEP2
ITDJSNLDAPC
ITDJSNUIP1
ITDJSNUIT1
ITDK12ADFS1
ITDK12ADFS2
ITDK12ADFSD1
ITDK12ADFSPROXY
ITDK12ADFSS1
ITDK12FIMPTL1
ITDK12FIMPTL2
ITDK12FIMPTLS1
ITDK12FIMPTLS2
itdk12vpointweb
ITDLANSWEEPER
ITDLIST
ITDLISTDEV
ITDLOCALITY
ITDMBAM1
ITDMFA1
ITDMFA2
ITDMFA3
ITDMFAPORTAL1
ITDMFASERVER1
ITDMFASQL1
ITDMFASQL2
ITDMFAT1
ITDMFAVPNAGENT1
ITDMFAVPNAGENT2
ITDMIDMZT1
ITDMIGATEWAY
ITDMIGATEWAYT1
ITDMITRANSFERP1
ITDMMISTMART
ITDNADEFENDP1
ITDNANFSTEST
itdnbaio
itdnbweb1
ITDNET35P1
ITDNET35P2
ITDNET35T1
ITDNET35T2
ITDNETP1
ITDNETP2
ITDNETP4
ITDNETT1
ITDNETT2
ITDNETT4
ITDNETU2
ITDNPS2
ITDOMBNETP1
ITDOMBNETT1
ITDOMBWR
ITDOPENSCAN1
ITDOPENSCAN1TST
ITDOPENSCAN2
ITDOUTMAN1
ITDOWAPPTEST
ITDOWAPROD
ITDPAESMEXT1
ITDPAESMINT1
ITDPREMIERP1
ITDPREMIERP2
ITDPREMIERSQLT1
ITDPREMIERT1
ITDPREMIERTRN1
ITDPS-IMAGES
ITDPS-UPDATE
ITDPV2
ITDPVTEST
ITDPWDSG
ITDRATRPT2
ITDRATRPT3
ITDRATRPT4
ITDRFAX
itdrpaorchp1
itdrpaorcht1
ITDRRISYNERGY
itdsaoicp1
ITDSCCM1
ITDSCCM1REPORT
ITDSCCMP2
ITDSCCMP2MAC1
ITDSCCMUP1
ITDSCCMWSUS1
ITDSCCMWSUSUP1
ITDSHSAPPS
ITDSHSPRESRVP1
ITDSITXPR4
ITDSKYPEBIS1
ITDSKYPEBIS2
ITDSKYPEDIR1
ITDSKYPEEDGE1
ITDSKYPEEDGET1
ITDSKYPEFET1
ITDSKYPEMAN1
ITDSKYPEMAN2
ITDSLDSMLDE
ITDSLDSSPPROD2
ITDSLEDD1HE
ITDSLEDD1K12
ITDSLRWNDS
ITDSLRWNDSTEST
ITDSOSBLSAPPP1
ITDSOSBLSAPPT1
ITDSOSBLSWEBP1
ITDSOSBLSWEBT1
ITDSOSBPIWP1
ITDSOSBPIWP2
ITDSOSBPWT1
ITDSOSBPWT2
ITDSOSINDEXP1
ITDSOSINDEXP2
ITDSOSINDEXT1
ITDSOSINDEXTRN1
ITDSOSVIPP1
ITDSOSVIPP2
ITDSOSVIPT1
ITDSOSVOICESP1
ITDSOSVOICESP2
ITDSOSVOICEST1
ITDSPDEVK12TST
ITDSPSLDSPROD
ITDSPSPROD
ITDSPSPROD1DR13
ITDSPSPRODSERV
ITDSPSTEST
ITDSTORADMIN3
ITDTAXAPPP2
ITDTEAMP1
ITDTEAMT1
ITDTESTDEVCA6
ITDTEXCAS1
ITDTEXCAS2
ITDTEXMBX1
ITDTEXMBX2
ITDTFSP2
ITDTFSP3
ITDTFSSPPROD
ITDTFST2
ITDTRVPHRAPP1
ITDTRVPHRGW
ITDTSKYPEFE1
ITDTSKYPEFE2
ITDTSKYPEFE3
ITDTSKYPEFE4
ITDVMVCP1SCRIPT
ITDVMVCP2SCRIPT
ITDVMVRAIAASP1
ITDVMVRAIAAST1
ITDWSIEXTAPPC1
ITDWSIEXTAPPC2
ITDWSIEXTAPPD1
ITDWSIEXTAPPP1
ITDWSIEXTAPPP2
ITDWSIEXTAPPT1
ITDWSIEXTAPPT2
ITDWSIEXTSQLT1
ITDWSIEXTSRVP1
ITDWSIEXTSRVT1
ITDWSIITSM
ITDWSINETP1
ITDWSINETT1
ITDWSINETT2
ITDWSIPRDWEB01
ITDWSITESTCERT1
ITDWSITESTDEVM1
ITDWSITESTDEVR1
ITDWSITESTSYS01
ITDWSITESTUAT01
ITDWSSPROD
ITDWSSTEST
ITDWSUS
ITDWWW10
ITDWWW11
ITDWWW12
ITDWWW3
ITDWWW7
ITDWWW8
ITDWWW9
itdwwwdev10
ITDWWWDEV3
ITDWWWDEV7
ITDWWWDEV8
ITDWWWDEV9
NODAK00
NODAK02
NODAK04
WSIAPP1
"@
$servers = ConvertTo-Array -MultiLineString $IISservers
$result = @()
$func = {
try {
Import-Module WebAdministration
#$result=@()
$sites = Get-ChildItem IIS:\Sites\
ForEach ($site in $sites) {
$id = $site.id
$logdir = $site.logfile.directory + "\w3svc" + $id
If ($logdir -like "*%SystemDrive%*") {
$location = $site.logfile.directory -replace '%SystemDrive%', 'C:'
}
else {
$Location = $logdir
}
$LogFilesAll = Get-ChildItem $location -Recurse
$LogFiles15D = $LogFilesAll | Where-Object LastWriteTime -lt ((Get-Date).AddDays(-15))
$LogFiles30D = $LogFilesAll | Where-Object LastWriteTime -lt ((Get-Date).AddDays(-30))
$LogFiles60D = $LogFilesAll | Where-Object LastWriteTime -lt ((Get-Date).AddDays(-60))
$LogFiles90D = $LogFilesAll | Where-Object LastWriteTime -lt ((Get-Date).AddDays(-90))
$OldestDate = ($LogFilesAll | Sort-Object LastWriteTime | Select-Object -First 1).LastWriteTime
$obj = [PSCustomObject]@{
SiteName = $site.Name;
LogDir = $location;
LogsAll = [math]::round(($LogFilesAll | measure-object -sum length).sum/1MB, 2);
Logs15D = [math]::round(($LogFiles15D | measure-object -sum length).sum/1MB, 2);
Logs30D = [math]::round(($LogFiles30D | measure-object -sum length).sum/1MB, 2);
Logs60D = [math]::round(($LogFiles60D | measure-object -sum length).sum/1MB, 2);
Logs90D = [math]::round(($LogFiles90D | measure-object -sum length).sum/1MB, 2);
OldestFile = $OldestDate;
}
$obj
}
}
catch {
}
}
$result = Invoke-Command -Credential $AdminCred -ScriptBlock $func -ComputerName $servers
$funcCleanup = {
Get-Childitem -Path $args[0] | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$args[1]) }
}
ForEach ($site in $result) {
Invoke-Command -ComputerName $site.PSComputerName -ScriptBlock $funcCleanup -Credential $AdminCred -ArgumentList $site.PSComputerName, $site.LogDir, 90
}
Binary file not shown.
+48
View File
@@ -0,0 +1,48 @@
$InvokeResult = Invoke-Command -ComputerName itdkms3.nd.gov -Credential $PrvCred -ScriptBlock {
Get-WinEvent -LogName "Key Management Service" -MaxEvents 100000 | Select-Object TimeCreated, `
@{n='Hostname';e={$_.Message.Split("`n")[2].Split(',')[2]}}, `
@{n='ErrorCode';e={$_.Message.Split("`n")[2].Split(',')[0]}}, `
@{n='FullEntry';e={$_.Message.Split("`n")[2]}}, `
@{n='ActivationID';e={$_.Message.Split("`n")[2].Split(',')[8]}}, `
@{n='ProductName';e={
switch ($_.Message.Split("`n")[2].Split(',')[8]) {
'de32eafd-aaee-4662-9444-c1befb41bde2' { "Windows Server 2019 Standard" }
'34e1ae55-27f8-4950-8877-7a03be5fb181' { "Windows Server 2019 Datacenter" }
'8c1c5410-9f39-4805-8c9d-63a07706358f' { "Windows Server 2016 Standard" }
'b3ca044e-a358-4d68-9883-aaa2941aca99' { "Windows Server 2012R2 Standard" }
'73111121-5638-40f6-bc11-f1d7b0d64300' { "Windows 10 Enterprise" }
'd450596f-894d-49e0-966a-fd39ed4c4c64' { "Office 16, Office16ProPlusVL_KMS_Client edition" }
'b234abe3-0857-4f9c-b05a-4dc314f85557' { "Visio or Project 2016 ??" }
'85dd8b5f-eaa4-4af3-a628-cce9e77c9a03' { "Office 20xx C2R (deployed spring 2022 on Servers)" }
'21c56779-b449-4d20-adfc-eece0e1ad74b' { "Windows Server 2016 Datacenter"}
'e13ac10e-75d0-4aff-a0cd-764982cf541c' { "Visio or Project 2013 ??"}
'b13afb38-cd79-4ae5-9f7f-eed058d750ca' { "Office15 / Office Standard 2013 ??"}
'32d2fab3-e4a8-42c2-923b-4bf4fd13e6ee' { "Windows 10 Enterprise LTSC 2021 ??"}
'2de67392-b7a7-462a-b1ca-108dd189f588' { "Windows 10 Pro"}
'829b8110-0e6f-4349-bca4-42803577788d' { "Office16ProjectProXC2RVL_KMS_ClientC2R ??"}
'b322da9c-a2e2-4058-9e4e-f59a6970bd69' { "Office15 / Office 2013 Professional Plus"}
'dedfa23d-6ed1-45a6-85dc-63cae0546de6' { "Office16StandardVL_KMS_Client"}
Default { "" }
}
}} | sort-object TimeCreated -Descending }
$InvokeResult | export-csv "D:\itdkms3-log.csv"
<#
Run
Get-WMIObject -Class SoftwareLicensingProduct
on client device to determine which software is which activation ID
Windows Server 2019 Standard - de32eafd-aaee-4662-9444-c1befb41bde2
Windows Server 2019 Datacenter - 34e1ae55-27f8-4950-8877-7a03be5fb181
Windows Server 2016 Standard - 8c1c5410-9f39-4805-8c9d-63a07706358f
Windows Server 2012R2 Standard - b3ca044e-a358-4d68-9883-aaa2941aca99
Windows 10 Enterprise - 73111121-5638-40f6-bc11-f1d7b0d64300
Office 16, Office16ProPlusVL_KMS_Client edition - d450596f-894d-49e0-966a-fd39ed4c4c64
Visio or Project 2016 ?? - b234abe3-0857-4f9c-b05a-4dc314f85557
Office 20xx (deployed spring 2022 on Servers) - 85dd8b5f-eaa4-4af3-a628-cce9e77c9a03
#>
+28
View File
@@ -0,0 +1,28 @@
##### Fix locally, run as admin
Set-Location "C:\Program Files\Microsoft Office\Office16\" # might be a different folder for different versions
# get current status
cscript .\ospp.vbs /dstatus
# set KMS server and activate
cscript .\ospp.vbs /sethst:kms.nd.gov
cscript .\ospp.vbs /act
##### Fix remotely, will prompt for PRV credentials
$Credential = Get-Credential -Message "Enter your PRV credentials"
# Get current status
Invoke-Command -Credential $Credential -ComputerName server01,server02,server03 -ScriptBlock {
Set-Location "C:\Program Files\Microsoft Office\Office16\"
cscript .\ospp.vbs /dstatus
}
# Set KMS server and activate
Invoke-Command -Credential $Credential -ComputerName server01,server02,server03 -ScriptBlock {
Set-Location "C:\Program Files\Microsoft Office\Office16\"
cscript .\ospp.vbs /sethst:kms.nd.gov
cscript .\ospp.vbs /act
}
+25
View File
@@ -0,0 +1,25 @@
##### Fix locally, run as admin (or system)
# get current status
cscript C:\windows\system32\slmgr.vbs -dli
# set KMS server and activate
cscript C:\windows\system32\slmgr.vbs -skms kms.nd.gov
cscript C:\windows\system32\slmgr.vbs -ato
##### Fix remotely, will prompt for PRV credentials
$Credential = Get-Credential -Message "Enter your PRV credentials"
# Get current status
Invoke-Command -Credential $Credential -ComputerName server01,server02,server03 -ScriptBlock {
cscript C:\windows\system32\slmgr.vbs -dli
}
# Set KMS server and activate
Invoke-Command -Credential $Credential -ComputerName server01,server02,server03 -ScriptBlock {
cscript C:\windows\system32\slmgr.vbs -skms kms.nd.gov
cscript C:\windows\system32\slmgr.vbs -ato
}
+45
View File
@@ -0,0 +1,45 @@
Function Convert-RvNetInt64ToIpAddress()
{
<#
.DESCRIPTION
Developer
Developer: Rudolf Vesely, http://rudolfvesely.com/
Copyright (c) Rudolf Vesely. All rights reserved
License: Free for private use only
#>
Param
(
[int64]
$Int64
)
# Return
'{0}.{1}.{2}.{3}' -f ([math]::Truncate($Int64 / 16777216)).ToString(),
([math]::Truncate(($Int64 % 16777216) / 65536)).ToString(),
([math]::Truncate(($Int64 % 65536)/256)).ToString(),
([math]::Truncate($Int64 % 256)).ToString()
}
Function Convert-RvNetSubnetMaskCidrToClasses
{
<#
.DESCRIPTION
Developer
Developer: Rudolf Vesely, http://rudolfvesely.com/
Copyright (c) Rudolf Vesely. All rights reserved
License: Free for private use only
#>
Param
(
[int]
$SubnetMaskCidr
)
# Return
Convert-RvNetInt64ToIpAddress -Int64 ([convert]::ToInt64(('1' * $SubnetMaskInt + '0' * (32 - $SubnetMaskInt)), 2))
}
$SubnetMaskInt = 28
+47
View File
@@ -0,0 +1,47 @@
$Switch23996 = Get-Content D:\VLAN-23996.txt
$Switch23997 = Get-Content D:\VLAN-23997.txt
$Switch23998 = Get-Content D:\VLAN-23998.txt
$Switch23999 = Get-Content D:\VLAN-23999.txt
$VC1PortGroups = Get-VirtualPortGroup -VirtualSwitch "dvSwitch-PDC-Data-Server"
$VC2PortGroups = Get-VirtualPortGroup -VirtualSwitch "dvSwitch-SDC-Data-Server"
$AllPortGroups = ($VC1PortGroups + $VC2PortGroups) | select -Unique Name | Sort-Object Name
$AllVmNetworkAdapters = ((Get-VM | Where-Object { $_.ExtensionData.Summary.Config.ManagedBy.Type -ne "placeholderVm" }) | Get-NetworkAdapter)
$Result = [System.Collections.ArrayList]@()
ForEach ($PortGroup in $AllPortGroups) {
$obj = $null
$VlanInt = [int]$PortGroup.name.split('_')[1]
$obj = [PSCustomObject]@{
'VlanStr' = $PortGroup.name.split('_')[1];
'CIDR' = $PortGroup.name.split('_')[2] + '/' + $PortGroup.Name.split('_')[3];
'Description' = ($Switch23996 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[2];
'vNic_Count' = ($AllVmNetworkAdapters | where-object NetworkName -like "*$CIDR*").count
'23996-61' = ($Switch23996 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*61*"
'23996-69' = ($Switch23996 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*69*"
'23996-73' = ($Switch23996 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*73*"
'23996-81' = ($Switch23996 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*81*"
'23996-89' = ($Switch23996 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*89*"
'23997-61' = ($Switch23997 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*61*"
'23997-69' = ($Switch23997 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*69*"
'23997-73' = ($Switch23997 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*73*"
'23997-81' = ($Switch23997 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*81*"
'23997-89' = ($Switch23997 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*89*"
'23998-61' = ($Switch23998 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*61*"
'23998-69' = ($Switch23998 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*69*"
'23998-81' = ($Switch23998 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*81*"
'23998-89' = ($Switch23998 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*89*"
'23999-61' = ($Switch23999 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*61*"
'23999-69' = ($Switch23999 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*69*"
'23999-81' = ($Switch23999 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*81*"
'23999-89' = ($Switch23999 | Where-Object { $_ -like ("*v" + $VlanInt + "*") }).split(' ')[5] -like "*89*"
}
#Write-Output $obj
$null = $Result.Add($obj)
}
+46
View File
@@ -0,0 +1,46 @@
<#
.Synopsis
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
#>
function Get-PropertyObjectTest
{
[CmdletBinding()]
Param
(
[string[]]
$ProcessName
)
Begin
{
}
Process
{
$MyArrayList = [System.Collections.ArrayList]@()
$null = $MyArrayList.Add($obj)
ForEach ($Process in $ProcessName)
{
$Output = Get-Process -Name $Process
$obj=[PSCustomObject]@{
'ProcessName' = $Output.Name;
'CPU' = $Output.CPU -as [int];
'VMGB' = $Output.VirtualMemorySize64 / 1GB -as [int];
'WSMB' = $Output.WorkingSet64 / 1MB -as [int];
}
#Write-Output $obj
$null = $MyArrayList.Add($obj)
}
}
End
{
}
}
+38
View File
@@ -0,0 +1,38 @@
FileAndStorage-Services
Storage-Services
Web-Server
Web-WebServer
Web-Common-Http
Web-Default-Doc
Web-Dir-Browsing
Web-Http-Errors
Web-Static-Content
Web-Health
Web-Http-Logging
Web-Performance
Web-Stat-Compression
Web-Security
Web-Filtering
Web-App-Dev
Web-Net-Ext45
Web-Asp-Net45
Web-ISAPI-Ext
Web-ISAPI-Filter
Web-Mgmt-Tools
Web-Mgmt-Console
NET-Framework-45-Features
NET-Framework-45-Core
NET-Framework-45-ASPNET
NET-WCF-Services45
NET-WCF-TCP-PortSharing45
RDC
System-DataArchiver
Windows-Defender
PowerShellRoot
PowerShell
PowerShell-ISE
WoW64-Support
XPS-Viewer
@@ -0,0 +1,8 @@
#Step 1 - Copy dll
If(!(Test-Path 'C:\Program Files\PackageManagement\ProviderAssemblies\nuget\2.8.5.208\'))
{
New-Item -Path 'C:\Program Files\PackageManagement\ProviderAssemblies\nuget\2.8.5.208\' -ItemType Directory -Force
}
Copy-Item -Path '\\itdsccmp2.nd.gov\PowerShell_Repository\Microsoft.PackageManagement.NuGetProvider.dll' -Destination 'C:\Program Files\PackageManagement\ProviderAssemblies\nuget\2.8.5.208\Microsoft.PackageManagement.NuGetProvider.dll' -Force
Exit
@@ -0,0 +1,3 @@
# Step 2 RegisterPSRepo / Install Newest Modules
Register-PSRepository -Name "NDGOV_SCCM" -SourceLocation "\\itdsccmp2.nd.gov\PowerShell_Repository" -PublishLocation "\\itdsccmp2.nd.gov\PowerShell_Repository" -InstallationPolicy Trusted -PackageManagementProvider nuget
@@ -0,0 +1,2 @@
# Step 3 Install Modules
Find-Module ITD.Global,ITD.Windows -Repository NDGOV_SCCM | Install-Module
@@ -0,0 +1,2 @@
New-ITDExpiredFilesSchedule
New-ITDExpiredFilesJSON
+36
View File
@@ -0,0 +1,36 @@
Invoke-RestMethod -Method Post -Uri "https://itdpv.nd.gov/api/passwords" -ContentType "application/json" -Body $PasswordJson
Invoke-RestMethod -Method Get -Uri 'https://itdpv.nd.gov/winapi/passwords/20841' -Credential $PrvCred
$Uri = 'https://itdpv.nd.gov/winapi/searchpasswords/?search=zm'
$x=Invoke-RestMethod -Method Get -Uri $Uri -Credential $PrvCred
$Uri = 'https://itdpv.nd.gov/winapi/passwordlists/377'
Invoke-RestMethod -Method Get -Uri $Uri -Credential $PrvCred
# Retrieving password
$PasswordstateUrl = 'https://itdpv.nd.gov/winapi/passwords/18824'
Invoke-Restmethod -Method GET -Uri $PasswordstateUrl -Credential $PrvCred
# search for password
$Uri = 'https://itdpv.nd.gov/winapi/searchpasswords/?search=M365'
Invoke-RestMethod -Method Get -Uri $Uri -Credential $PrvCred
# adding a password
$jsonData = '
{
"PasswordListID":"53",
"Title":"itdzmbuild01.nd.gov",
"UserName":"test",
"password":"TESTpass12#$%"
}
'
$PasswordstateUrl = 'https://itdpv.nd.gov/winapi/passwords'
$result = Invoke-Restmethod -Method Post -Uri $PasswordstateUrl -ContentType "application/json" -Body $jsonData -Credential $PrvCred
+8
View File
@@ -0,0 +1,8 @@
#Register-PSRepository -Name NDGOV -SourceLocation 'https://ndgov.pkgs.visualstudio.com/_packaging/ITD3/nuget/v2' -PublishLocation 'https://ndgov.pkgs.visualstudio.com/_packaging/ITD3/nuget/v2' -InstallationPolicy Trusted -Credential $AdoCred
Register-PSRepository -Name ITD_PwshGallery `
-SourceLocation "https://powershell.nd.gov/ITD_PwshGallery/nuget/" `
-PublishLocation "https://powershell.nd.gov/ITD_PwshGallery/nuget/" `
-InstallationPolicy Trusted
+11
View File
@@ -0,0 +1,11 @@
$ImportCsv = Import-Csv -Path 'D:\OneDrive - State of North Dakota\CleanupFileLocations.csv'
$FilesToDelete=@()
ForEach($Directory in $ImportCsv) {
$GetChildItemParams = @{
Path = $Directory.Path
}
If($Directory.Filter){$GetChildItemParams += @{Filter = $Directory.Filter}}
If($Directory.Recursive -eq $true){$GetChildItemParams += @{Recurse = $true}}
$Files = Get-ChildItem @GetChildItemParams | Where-Object LastWriteTime -lt (Get-Date).AddDays(-$Directory.DaysToKeep)
}
+34
View File
@@ -0,0 +1,34 @@
$func = {
Import-Module "D:\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
Set-Location ITD:\
switch ((Get-Date).Day) {
{ $_ -ge 10 -and $_ -le 19 } {
$CollectionName = 'All-MW-Monthly, 1st Thursday After 2nd Tuesday'
$Platform = 'Test'
}
{ $_ -ge 20 -and $_ -le 31 } {
$CollectionName = 'All-MW-Monthly, 2nd Sunday After 2nd Tuesday'
$Platform = 'Production'
}
Default {
$CollectionName = $null
Exit
}
}
$PlatformStr = "SCCM-MicrosoftUpdates-" + $Platform + "Servers"
Get-CMDevice -CollectionName $CollectionName | Select-Object Name, @{n = 'DashboardPlatform'; e = { $PlatformStr } }
}
$servers = (Invoke-Command -ScriptBlock $func -ComputerName itdsccmp2.nd.gov -Credential $PrvCred)
$postParams = [PSCustomObject]@{
AutomationName = "Infra-Servers-SCCM";
Action = "Patching";
Units = [int][math]::round($servers.count * 7, 0);
Platform = ($servers | Select-Object -First 1).DashboardPlatform;
}
Invoke-RestMethod -Uri http://itdnettools.nd.gov/services/automation-tracking.py -Method POST -Body ($postParams | ConvertTo-Json)
+97
View File
@@ -0,0 +1,97 @@
#MAK & ESU discovery v2
$Esu1Bool = $false
$Esu2Bool = $false
$MakBool = $false
$OS = (Get-WMIObject Win32_OperatingSystem).Caption
Write-Verbose $OS
switch ($OS) {
'Microsoft Windows Server 2008 R2 Datacenter ' {
write-verbose "switch datacenter edition"
$MakId = '4ae528f4-05c3-446e-90ea-a4fbd460b83a'
$MakKey = 'MF2F8-YGGFX-6MKDF-PCM29-7BYDG'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd' #activationid
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
}
'Microsoft Windows Server 2008 R2 Enterprise ' {
write-verbose "switch enterprise edition"
$MakId = '6a4bd364-4b60-4856-a727-efb59d94348e'
$MakKey = '3YY4J-742QP-GPKP9-G2R6W-K6DDM'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
}
'Microsoft Windows Server 2008 R2 Standard ' {
write-verbose "switch standard edition"
$MakId = ''
$MakKey = '3YY4J-742QP-GPKP9-G2R6W-K6DDM'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
}
'Microsoft Windows 7 Enterprise ' {
write-verbose "switch Win7 enterprise edition"
$MakId = '9abf5984-9c16-46f2-ad1e-7fe15931a8dd'
$MakKey = 'PRV3H-98HJK-6KKBF-RHYTM-JWCRV'
$Esu1Id = '77db037b-95c3-48d7-a3ab-a9c6d41093e0'
$Esu1Key = 'MJCJ8-24DFX-VGK6H-XYBQ7-F6PR8'
$Esu2Id = '0e00c25d-8795-4fb7-9572-3803d91b6880'
$Esu2Key = 'WX34W-WG8MH-TWWCV-PXK96-RDMTJ'
}
'Microsoft® Windows Server® 2008 Standard ' {
write-verbose "switch 08 Standard"
$MakId = 'ad2542d4-9154-4c6d-8a44-30f11ee96989'
$MakKey = 'GQK9D-CT4WQ-9KJ87-FKMT8-MR73Q'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
}
'Microsoft® Windows Server® 2008 Enterprise ' {
write-verbose "switch 08 Enterprise"
$MakId = 'bb1d27c4-959d-4f82-b0fd-c02a7be54732'
$MakKey = 'GQK9D-CT4WQ-9KJ87-FKMT8-MR73Q'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
}
}
$software = Get-WMIObject -Class SoftwareLicensingProduct
$EsuYear1 = $software | Where-Object { $_.Id -eq $Esu1Id }
If ($EsuYear1) {
If ($EsuYear1.LicenseStatus -eq '1') {
$Esu1Bool = $true
}
}
$EsuYear2 = $software | Where-Object { $_.Id -eq $Esu2Id }
If ($EsuYear2) {
If ($EsuYear2.LicenseStatus -eq '1') {
$Esu2Bool = $true
}
}
$Mak = $software | where-object { $_.Id -eq $MakId }
If ($Mak) {
If ($Mak.LicenseStatus -eq 1) {
$MakBool = $true
}
}
If ($Esu1bool -eq $true -and $Esu2Bool -eq $true -and $Makbool -eq $true) {
$compliant = $true
}
else {
$compliant = $false
}
$compliant
+121
View File
@@ -0,0 +1,121 @@
#MAK & ESU discovery v3.1
$Esu1Bool = $false
$Esu2Bool = $false
$Esu3Bool = $false
$MakBool = $false
$OS = (Get-WMIObject Win32_OperatingSystem).Caption
Write-Verbose $OS
switch ($OS) {
'Microsoft Windows Server 2008 R2 Datacenter ' {
write-verbose "switch datacenter edition"
$MakId = '4ae528f4-05c3-446e-90ea-a4fbd460b83a'
$MakKey = '33YCD-89CD2-RMYVW-RGX7W-R9XRM'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd' #activationid
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft Windows Server 2008 R2 Enterprise ' {
write-verbose "switch enterprise edition"
$MakId = '6a4bd364-4b60-4856-a727-efb59d94348e'
$MakKey = 'TB9WQ-WKHVH-W7946-WJTVV-Y6QDD'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft Windows Server 2008 R2 Standard ' {
write-verbose "switch standard edition"
$MakId = ''
$MakKey = 'TB9WQ-WKHVH-W7946-WJTVV-Y6QDD'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft Windows 7 Enterprise ' {
write-verbose "switch Win7 enterprise edition"
$MakId = '9abf5984-9c16-46f2-ad1e-7fe15931a8dd'
$MakKey = 'PRV3H-98HJK-6KKBF-RHYTM-JWCRV'
$Esu1Id = '77db037b-95c3-48d7-a3ab-a9c6d41093e0'
$Esu1Key = 'MJCJ8-24DFX-VGK6H-XYBQ7-F6PR8'
$Esu2Id = '0e00c25d-8795-4fb7-9572-3803d91b6880'
$Esu2Key = 'WX34W-WG8MH-TWWCV-PXK96-RDMTJ'
$Esu3Id = '4220f546-f522-46df-8202-4d07afd26454'
$Esu3Key = 'TF336-89RVD-X2FJJ-YV3KF-Q6KPF'
}
'Microsoft® Windows Server® 2008 Standard ' {
write-verbose "switch 08 Standard"
$MakId = 'ad2542d4-9154-4c6d-8a44-30f11ee96989'
$MakKey = 'GQK9D-CT4WQ-9KJ87-FKMT8-MR73Q'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft® Windows Server® 2008 Enterprise ' {
write-verbose "switch 08 Enterprise"
$MakId = 'bb1d27c4-959d-4f82-b0fd-c02a7be54732'
$MakKey = 'GQK9D-CT4WQ-9KJ87-FKMT8-MR73Q'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
}
$software = Get-WMIObject -Class SoftwareLicensingProduct
$EsuYear1 = $software | Where-Object { $_.Id -eq $Esu1Id }
If ($EsuYear1) {
If ($EsuYear1.LicenseStatus -eq '1') {
$Esu1Bool = $true
}
}
$EsuYear2 = $software | Where-Object { $_.Id -eq $Esu2Id }
If ($EsuYear2) {
If ($EsuYear2.LicenseStatus -eq '1') {
$Esu2Bool = $true
}
}
$EsuYear3 = $software | Where-Object { $_.Id -eq $Esu3Id }
If ($EsuYear3) {
If ($EsuYear3.LicenseStatus -eq '1') {
$Esu3Bool = $true
}
}
$Mak = $software | where-object { $_.Id -eq $MakId }
If ($Mak) {
If ($Mak.LicenseStatus -eq 1) {
$MakBool = $true
}
}
If ($Esu1bool -eq $true -and $Esu2Bool -eq $true -and $Esu3Bool -eq $true -and $Makbool -eq $true) {
$compliant = $true
}
else {
$compliant = $false
}
$compliant
#2008 std/ent TB9WQ-WKHVH-W7946-WJTVV-Y6QDD
#2008 dcntr 33YCD-89CD2-RMYVW-RGX7W-R9XRM
+68
View File
@@ -0,0 +1,68 @@
#MAK & ESU remediation v2
$OS = (Get-WMIObject Win32_OperatingSystem).Caption
write-verbose $OS
switch ($OS) {
'Microsoft Windows Server 2008 R2 Datacenter ' {
write-verbose "switch datacenter edition"
$MakId = '4ae528f4-05c3-446e-90ea-a4fbd460b83a'
$MakKey = 'MF2F8-YGGFX-6MKDF-PCM29-7BYDG'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd' #activationid
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
}
'Microsoft Windows Server 2008 R2 Enterprise ' {
write-verbose "switch enterprise edition"
$MakId = '6a4bd364-4b60-4856-a727-efb59d94348e'
$MakKey = '3YY4J-742QP-GPKP9-G2R6W-K6DDM'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
}
'Microsoft Windows Server 2008 R2 Standard ' {
write-verbose "switch standard edition"
$MakId = ''
$MakKey = '3YY4J-742QP-GPKP9-G2R6W-K6DDM'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
}
'Microsoft Windows 7 Enterprise ' {
write-verbose "switch Win7 enterprise edition"
$MakId = '9abf5984-9c16-46f2-ad1e-7fe15931a8dd'
$MakKey = 'PRV3H-98HJK-6KKBF-RHYTM-JWCRV'
$Esu1Id = '77db037b-95c3-48d7-a3ab-a9c6d41093e0'
$Esu1Key = 'MJCJ8-24DFX-VGK6H-XYBQ7-F6PR8'
$Esu2Id = '0e00c25d-8795-4fb7-9572-3803d91b6880'
$Esu2Key = 'WX34W-WG8MH-TWWCV-PXK96-RDMTJ'
}
'Microsoft® Windows Server® 2008 Standard ' {
write-verbose "switch 08 Standard"
$MakId = 'ad2542d4-9154-4c6d-8a44-30f11ee96989'
$MakKey = 'GQK9D-CT4WQ-9KJ87-FKMT8-MR73Q'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
}
'Microsoft® Windows Server® 2008 Enterprise ' {
write-verbose "switch 08 Enterprise"
$MakId = 'bb1d27c4-959d-4f82-b0fd-c02a7be54732'
$MakKey = 'GQK9D-CT4WQ-9KJ87-FKMT8-MR73Q'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
}
}
cscript C:\Windows\System32\slmgr.vbs -ipk $MakKey
cscript C:\Windows\System32\slmgr.vbs -ato $MakId
cscript C:\Windows\System32\slmgr.vbs -ipk $Esu1Key
cscript C:\Windows\System32\slmgr.vbs -ato $Esu1Id
cscript C:\Windows\System32\slmgr.vbs -ipk $Esu2Key
cscript C:\Windows\System32\slmgr.vbs -ato $Esu2Id
+82
View File
@@ -0,0 +1,82 @@
#MAK & ESU remediation v3.1
$OS = (Get-WMIObject Win32_OperatingSystem).Caption
write-verbose $OS
switch ($OS) {
'Microsoft Windows Server 2008 R2 Datacenter ' {
write-verbose "switch datacenter edition"
$MakId = '4ae528f4-05c3-446e-90ea-a4fbd460b83a'
$MakKey = '33YCD-89CD2-RMYVW-RGX7W-R9XRM'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd' #activationid
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft Windows Server 2008 R2 Enterprise ' {
write-verbose "switch enterprise edition"
$MakId = '6a4bd364-4b60-4856-a727-efb59d94348e'
$MakKey = 'TB9WQ-WKHVH-W7946-WJTVV-Y6QDD'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft Windows Server 2008 R2 Standard ' {
write-verbose "switch standard edition"
$MakId = ''
$MakKey = 'TB9WQ-WKHVH-W7946-WJTVV-Y6QDD'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft Windows 7 Enterprise ' {
write-verbose "switch Win7 enterprise edition"
$MakId = '9abf5984-9c16-46f2-ad1e-7fe15931a8dd'
$MakKey = 'PRV3H-98HJK-6KKBF-RHYTM-JWCRV'
$Esu1Id = '77db037b-95c3-48d7-a3ab-a9c6d41093e0'
$Esu1Key = 'MJCJ8-24DFX-VGK6H-XYBQ7-F6PR8'
$Esu2Id = '0e00c25d-8795-4fb7-9572-3803d91b6880'
$Esu2Key = 'WX34W-WG8MH-TWWCV-PXK96-RDMTJ'
$Esu3Id = '4220f546-f522-46df-8202-4d07afd26454'
$Esu3Key = 'TF336-89RVD-X2FJJ-YV3KF-Q6KPF'
}
'Microsoft® Windows Server® 2008 Standard ' {
write-verbose "switch 08 Standard"
$MakId = 'ad2542d4-9154-4c6d-8a44-30f11ee96989'
$MakKey = 'GQK9D-CT4WQ-9KJ87-FKMT8-MR73Q'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
'Microsoft® Windows Server® 2008 Enterprise ' {
write-verbose "switch 08 Enterprise"
$MakId = 'bb1d27c4-959d-4f82-b0fd-c02a7be54732'
$MakKey = 'GQK9D-CT4WQ-9KJ87-FKMT8-MR73Q'
$Esu1Id = '553673ed-6ddf-419c-a153-b760283472fd'
$Esu1Key = 'MMFTT-7FBRY-W9QYW-37FMB-TRPJK'
$Esu2Id = '04fa0286-fa74-401e-bbe9-fbfbb158010d'
$Esu2Key = '6P3TQ-J2C3Y-VK2TD-8P648-Y3TF6'
$Esu3Id = '16c08c85-0c8b-4009-9b2b-f1f7319e45f9'
$Esu3Key = '36FB4-RK77J-C867T-QPJBT-4PMW6'
}
}
cscript C:\Windows\System32\slmgr.vbs -ipk $MakKey
cscript C:\Windows\System32\slmgr.vbs -ato $MakId
cscript C:\Windows\System32\slmgr.vbs -ipk $Esu1Key
cscript C:\Windows\System32\slmgr.vbs -ato $Esu1Id
cscript C:\Windows\System32\slmgr.vbs -ipk $Esu2Key
cscript C:\Windows\System32\slmgr.vbs -ato $Esu2Id
cscript C:\Windows\System32\slmgr.vbs -ipk $Esu3Key
cscript C:\Windows\System32\slmgr.vbs -ato $Esu3Id
+4
View File
@@ -0,0 +1,4 @@
If (Get-WmiObject -query 'SELECT * FROM CCM_SoftwareUpdate' -namespace 'ROOT\ccm\ClientSDK' | where-object ArticleId -eq 5001078) {
([wmiclass]'ROOT\ccm\ClientSDK:CCM_SoftwareUpdatesManager').InstallUpdates([System.Management.ManagementObject[]] (Get-WmiObject -query 'SELECT * FROM CCM_SoftwareUpdate' -namespace 'ROOT\ccm\ClientSDK' | where-object ArticleId -eq 5001078))
}
+18
View File
@@ -0,0 +1,18 @@
$AvailableUpdates = (Get-WmiObject -query 'SELECT * FROM CCM_SoftwareUpdate' -namespace 'ROOT\ccm\ClientSDK')
If($AvailableUpdates){
([wmiclass]'ROOT\ccm\ClientSDK:CCM_SoftwareUpdatesManager').InstallUpdates([System.Management.ManagementObject[]] $AvailableUpdates)
}
([wmiclass]'ROOT\ccm\ClientSDK:CCM_ClientUtilities').DetermineIfRebootPending()
$InProgress = (Get-WmiObject -query 'SELECT * FROM CCM_SoftwareUpdate' -namespace 'ROOT\ccm\ClientSDK')
$Inprogress.percentcomplete
#as admin
$UpdateStatus = get-wmiobject -query "SELECT * FROM CCM_UpdateStatus" -namespace "root\ccm\SoftwareUpdates\UpdatesStore"
$InstalledUpdates = Get-HotFix | Where-Object InstalledOn -eq (Get-Date).Date
$UpdatesRemaining = Compare-Object $AvailableUpdates.ArticleId $InstalledUpdates.HotFixId.trim("KB")
$AvailableUpdates | where-object {$_.ArticleId -match $UpdatesRemaining.InputObject}
+3
View File
@@ -0,0 +1,3 @@
# New Builds Last 2 Days
select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_OPERATING_SYSTEM on SMS_G_System_OPERATING_SYSTEM.ResourceId = SMS_R_System.ResourceId WHERE (DateDiff(day, SMS_G_System_OPERATING_SYSTEM.InstallDate, GetDate()) < 2)
+84
View File
@@ -0,0 +1,84 @@
#msiexec /uninstall "{19A62C3B-3907-4CC0-B037-DFC883A347B3}" /q
#msiexec /uninstall "{D1607BEA-A9DC-449A-B7A5-770492376485}" /q
$Service = Get-Service -DisplayName "TSM Client Scheduler" -ErrorAction SilentlyContinue
If ($Service) {
Write-Warning "Stop TSM Client Scheduler service"
Get-Service -DisplayName "TSM Client Scheduler" | Stop-Service
Write-Warning "Remove TSM Client Scheduler service with dsmcutil"
$ServiceRemoval1 = Invoke-Expression -Command '& "C:\Program Files\Tivoli\TSM\baclient\dsmcutil.exe" remove /name:"TSM Client Scheduler"'
$ServiceRemoval2 = Invoke-Expression -Command '& "C:\Program Files\Tivoli\TSM\baclient\dsmcutil.exe" remove /name:"ISP Client Scheduler"'
If ($ServiceRemoval1 -match "The service was successfully removed." -or $ServiceRemoval2 -match "The service was successfully removed.") {
Write-Warning "TSM Client Scheduler service successfully removed"
}
Else {
Write-Error "TSM service removal error" -ErrorAction Stop
}
}
$TSMGuids = @(
"{2068FA80-E4DD-4F9D-AD94-AAF8AAB62142}",
"{F2299C3C-F4D2-4151-AD79-DBAB8DF7DBE6}",
"{89857B75-F612-49B8-83E4-081C4D8D2A2F}",
"{00F61113-3426-49C2-AFAF-E0ECDA4CF352}",
"{C04EDECE-BA6C-4E0D-9959-D30C5485316F}",
"{0EE10C4C-D8EC-48BA-A4B3-C05A5D660395}",
"{19A62C3B-3907-4CC0-B037-DFC883A347B3}",
"{D1F5E133-94F4-4BCE-95DD-656DD4E04B56}",
"{2724D1FA-B655-4EA2-A1AF-C6D2C4630F46}",
"{5A9BA69C-B7E8-49AC-8ACA-A4B1B7A1652F}",
"{66869291-1627-46DF-969C-57B10EBEA7DE}",
"{25A8256B-EB72-4DA5-87CB-0CBB52B8B37B}",
"{5B310A44-6A5B-41DB-964F-49D2292CE5F4}",
"{D1607BEA-A9DC-449A-B7A5-770492376485}",
"{6E2D5C0A-E7AC-4AA2-8C0B-1738E86C0142}"
)
$Service = Get-Service -DisplayName "TSM Client Scheduler" -ErrorAction SilentlyContinue
If ($Service) {
Write-Error "TSM service still exists error" -ErrorAction Stop
}
Else {
Write-Warning "Discover TSM installed apps"
Write-Warning "Start TSM Removal Loop"
ForEach ($Guid in $TSMGuids) {
Write-Warning "Removing $Guid"
$params = @{
"FilePath" = "C:\windows\system32\msiexec.exe"
"ArgumentList" = @(
"/uninstall"
"$Guid"
"/q"
)
"Verb" = "runas"
"PassThru" = $true
}
$uninstaller = start-process @params
$uninstaller.WaitForExit()
}
}
<#
$uninstaller = start-process @params
$uninstaller.WaitForExit()
Write-Warning "End TSM JVM Removal"
Write-Warning "Start TSM Client Removal"
$params = @{
"FilePath" = "C:\windows\system32\msiexec.exe"
"ArgumentList" = @(
"/uninstall"
"{D1607BEA-A9DC-449A-B7A5-770492376485}"
"/q"
)
"Verb" = "runas"
"PassThru" = $true
}
$uninstaller = start-process @params
$uninstaller.WaitForExit()
Write-Warning "End TSM Client Removal"
#>
Binary file not shown.
@@ -0,0 +1 @@
*.psd1 diff
@@ -0,0 +1 @@
*.zip
@@ -0,0 +1,167 @@
# Depends on SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
# It is assumed that the connection to VC and SRM Server have already been made
Function Get-SrmConfigReportSite {
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
Get-SrmServer $SrmServer |
Format-Table -Wrap -AutoSize @{Label="SRM Site Name"; Expression={$_.ExtensionData.GetSiteName()} },
@{Label="SRM Host"; Expression={$_.Name} },
@{Label="SRM Port"; Expression={$_.Port} },
@{Label="Version"; Expression={$_.Version} },
@{Label="Build"; Expression={$_.Build} },
@{Label="SRM Peer Site Name"; Expression={$_.ExtensionData.GetPairedSite().Name} }
}
Function Get-SrmConfigReportPlan {
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
Get-SrmRecoveryPlan -SrmServer $SrmServer | %{
$rp = $_
$rpinfo = $rp.GetInfo()
$peerState = $rp.GetPeer().State
$pgs = Get-SrmProtectionGroup -RecoveryPlan $rp
$pgnames = $pgs | %{ $_.GetInfo().Name }
$output = "" | select plan, state, peerState, groups
$output.plan = $rpinfo.Name
$output.state = $rpinfo.State
$output.peerState = $peerState
if ($pgnames) {
$output.groups = [string]::Join(",`r`n", $pgnames)
} else {
$output.groups = "NONE"
}
$output
} | Format-Table -Wrap -AutoSize @{Label="Recovery Plan Name"; Expression={$_.plan} },
@{Label="Recovery State"; Expression={$_.state} },
@{Label="Peer Recovery State"; Expression={$_.peerState} },
@{Label="Protection Groups"; Expression={$_.groups}}
}
Function Get-SrmConfigReportProtectionGroup {
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
Get-SrmProtectionGroup -SrmServer $SrmServer | %{
$pg = $_
$pginfo = $pg.GetInfo()
$pgstate = $pg.GetProtectionState()
$peerState = $pg.GetPeer().State
$rps = Get-SrmRecoveryPlan -ProtectionGroup $pg
$rpnames = $rps | %{ $_.GetInfo().Name }
$output = "" | select name, type, state, peerState, plans
$output.name = $pginfo.Name
$output.type = $pginfo.Type
$output.state = $pgstate
$output.peerState = $peerState
if ($rpnames) {
$output.plans = [string]::Join(",`r`n", $rpnames)
} else {
$output.plans = "NONE"
}
$output
} | Format-Table -Wrap -AutoSize @{Label="Protection Group Name"; Expression={$_.name} },
@{Label="Type"; Expression={$_.type} },
@{Label="Protection State"; Expression={$_.state} },
@{Label="Peer Protection State"; Expression={$_.peerState} },
@{Label="Recovery Plans"; Expression={$_.plans} }
}
Function Get-SrmConfigReportProtectedDatastore {
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
Get-SrmProtectionGroup -SrmServer $SrmServer -Type "san" | %{
$pg = $_
$pginfo = $pg.GetInfo()
$pds = Get-SrmProtectedDatastore -ProtectionGroup $pg
$pds | %{
$pd = $_
$output = "" | select datacenter, group, name, capacity, free
$output.datacenter = $pd.Datacenter.Name
$output.group = $pginfo.Name
$output.name = $pd.Name
$output.capacity = $pd.CapacityGB
$output.free = $pd.FreeSpaceGB
$output
}
} | Format-Table -Wrap -AutoSize -GroupBy "datacenter" @{Label="Datastore Name"; Expression={$_.name} },
@{Label="Capacity GB"; Expression={$_.capacity} },
@{Label="Free GB"; Expression={$_.free} },
@{Label="Protection Group"; Expression={$_.group} }
}
Function Get-SrmConfigReportProtectedVm {
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$srmversion = Get-SrmServerVersion -SrmServer $SrmServer
$srmMajorVersion, $srmMinorVersion = $srmversion -split "\."
Get-SrmProtectionGroup -SrmServer $SrmServer | %{
$pg = $_
$pginfo = $pg.GetInfo()
$pvms = Get-SrmProtectedVM -ProtectionGroup $pg
$rps = Get-SrmRecoveryPlan -ProtectionGroup $pg
$rpnames = $rps | %{ $_.GetInfo().Name }
$pvms | %{
$pvm = $_
if ($srmMajorVersion -ge 6 -or ($srmMajorVersion -eq 5 -and $srmMinorVersion -eq 8)) {
$rs = $rps | Select -First 1 | %{ $_.GetRecoverySettings($pvm.Vm.MoRef) }
}
$output = "" | select group, name, moRef, needsConfiguration, state, plans, priority, finalPowerState, preCallouts, postCallouts
$output.group = $pginfo.Name
$output.name = $pvm.Vm.Name
$output.moRef = $pvm.Vm.MoRef # this is necessary in case we can't retrieve the name when VC is unavailable
$output.needsConfiguration = $pvm.NeedsConfiguration
$output.state = $pvm.State
$output.plans = [string]::Join(",`r`n", $rpnames)
if ($rs) {
$output.priority = $rs.RecoveryPriority
$output.finalPowerState = $rs.FinalPowerState
$output.preCallouts = $rs.PrePowerOnCallouts.Count
$output.postCallouts = $rs.PostPowerOnCallouts.Count
}
$output
}
} | Format-Table -Wrap -AutoSize @{Label="VM Name"; Expression={$_.name} },
@{Label="VM MoRef"; Expression={$_.moRef} },
@{Label="Needs Config"; Expression={$_.needsConfiguration} },
@{Label="VM Protection State"; Expression={$_.state} },
@{Label="Protection Group"; Expression={$_.group} },
@{Label="Recovery Plans"; Expression={$_.plans} },
@{Label="Recovery Priority"; Expression={$_.priority} },
@{Label="Final Power State"; Expression={$_.finalPowerState} },
@{Label="Pre-PowerOn Callouts"; Expression={$_.preCallouts} },
@{Label="Post-PowerOn Callouts"; Expression={$_.postCallouts} }
}
Function Get-SrmConfigReport {
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
Get-SrmConfigReportSite -SrmServer $SrmServer
Get-SrmConfigReportPlan -SrmServer $SrmServer
Get-SrmConfigReportProtectionGroup -SrmServer $SrmServer
Get-SrmConfigReportProtectedDatastore -SrmServer $SrmServer
Get-SrmConfigReportProtectedVm -SrmServer $SrmServer
}
@@ -0,0 +1,34 @@
# Depends on SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
# It is assumed that the connections to active VC and SRM Server have already been made
Import-Module Meadowcroft.SRM -Prefix Srm
$TagCategoryName = 'Meadowcroft.SRM.VM'
$TagCategoryDescription = 'Tag category for tagging VMs with SRM state'
# If the tag category doesn't exist, create it and the relevant tags
$TagCategory = Get-TagCategory -Name $TagCategoryName -ErrorAction SilentlyContinue
if (-Not $TagCategory) {
Write-Output "Creating Tag Category $TagCategoryName"
$TagCategory = New-TagCategory -Name $TagCategoryName -Description $TagCategoryDescription -EntityType 'VirtualMachine'
Write-Output "Creating Tag SrmProtectedVm"
New-Tag -Name 'SrmProtectedVm' -Category $TagCategory -Description "VM protected by VMware SRM"
Write-Output "Creating Tag SrmTestVm"
New-Tag -Name 'SrmTestVm' -Category $TagCategory -Description "Test VM instantiated by VMware SRM"
Write-Output "Creating Tag SrmPlaceholderVm"
New-Tag -Name 'SrmPlaceholderVm' -Category $TagCategory -Description "Placeholder VM used by VMware SRM"
}
$protectedVmTag = Get-Tag -Name 'SrmProtectedVm' -Category $TagCategory
$testVmTag = Get-Tag -Name 'SrmTestVm' -Category $TagCategory
$placeholderVmTag = Get-Tag -Name 'SrmPlaceholderVm' -Category $TagCategory
# Assign protected tag to a VM, use ready state to get "local" protected VMs
Get-SrmProtectedVM -State Ready | %{ New-TagAssignment -Tag $protectedVmTag -Entity $(Get-VIObjectByVIView $_.Vm) | Out-Null }
# Assign test tag to a VM
Get-SrmTestVM | %{ New-TagAssignment -Tag $testVmTag -Entity $_ | Out-Null }
# Assign placeholder tag to a VM
Get-SrmPlaceholderVM | %{ New-TagAssignment -Tag $placeholderVmTag -Entity $_ | Out-Null }
@@ -0,0 +1,74 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -0,0 +1,422 @@
# SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
<#
.SYNOPSIS
Get the subset of protection groups matching the input criteria
.PARAMETER Name
Return protection groups matching the specified name
.PARAMETER Type
Return protection groups matching the specified protection group
type. For SRM 5.0-5.5 this is either 'san' for protection groups
consisting of a set of replicated datastores or 'vr' for vSphere
Replication based protection groups.
.PARAMETER RecoveryPlan
Return protection groups associated with a particular recovery
plan
.PARAMETER SrmServer
the SRM server to use for this operation.
#>
Function Get-ProtectionGroup {
[cmdletbinding()]
Param(
[Parameter(position=1)][string] $Name,
[string] $Type,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan[]] $RecoveryPlan,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
begin {
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
$pgs = @()
}
process {
if ($RecoveryPlan) {
foreach ($rp in $RecoveryPlan) {
$pgs += $RecoveryPlan.GetInfo().ProtectionGroups
}
$pgs = Select_UniqueByMoRef($pgs)
} else {
$pgs += $api.Protection.ListProtectionGroups()
}
}
end {
$pgs | ForEach-Object {
$pg = $_
$pgi = $pg.GetInfo()
$selected = (-not $Name -or ($Name -eq $pgi.Name)) -and (-not $Type -or ($Type -eq $pgi.Type))
if ($selected) {
Add-Member -InputObject $pg -MemberType NoteProperty -Name "Name" -Value $pgi.Name
$pg
}
}
}
}
<#
.SYNOPSIS
Get the subset of protected VMs matching the input criteria
.PARAMETER Name
Return protected VMs matching the specified name
.PARAMETER State
Return protected VMs matching the specified state. For protected
VMs on the protected site this is usually 'ready', for
placeholder VMs this is 'shadowing'
.PARAMETER ProtectionGroup
Return protected VMs associated with particular protection
groups
#>
Function Get-ProtectedVM {
[cmdletbinding()]
Param(
[Parameter(position=1)][string] $Name,
[VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectionState] $State,
[VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectionState] $PeerState,
[switch] $ConfiguredOnly,
[switch] $UnconfiguredOnly,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup[]] $ProtectionGroup,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan[]] $RecoveryPlan,
[string] $ProtectionGroupName,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
if ($null -eq $ProtectionGroup) {
$ProtectionGroup = Get-ProtectionGroup -Name $ProtectionGroupName -RecoveryPlan $RecoveryPlan -SrmServer $SrmServer
}
$ProtectionGroup | ForEach-Object {
$pg = $_
$pg.ListProtectedVms() | ForEach-Object {
# try and update the view data for the protected VM
try {
$_.Vm.UpdateViewData()
} catch {
Write-Error $_
} finally {
$_
}
} | Where-object { -not $Name -or ($Name -eq $_.Vm.Name) } |
where-object { -not $State -or ($State -eq $_.State) } |
where-object { -not $PeerState -or ($PeerState -eq $_.PeerState) } |
where-object { ($ConfiguredOnly -and $_.NeedsConfiguration -eq $false) -or ($UnconfiguredOnly -and $_.NeedsConfiguration -eq $true) -or (-not $ConfiguredOnly -and -not $UnconfiguredOnly) }
}
}
<#
.SYNOPSIS
Get the unprotected VMs that are associated with a protection group
.PARAMETER ProtectionGroup
Return unprotected VMs associated with particular protection
groups. For VR protection groups this is VMs that are associated
with the PG but not configured, For ABR protection groups this is
VMs on replicated datastores associated with the group that are not
configured.
#>
Function Get-UnProtectedVM {
[cmdletbinding()]
Param(
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup[]] $ProtectionGroup,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan[]] $RecoveryPlan,
[string] $ProtectionGroupName,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
if ($null -eq $ProtectionGroup) {
$ProtectionGroup = Get-ProtectionGroup -Name $ProtectionGroupName -RecoveryPlan $RecoveryPlan -SrmServer $SrmServer
}
$associatedVMs = @()
$protectedVmRefs = @()
$ProtectionGroup | ForEach-Object {
$pg = $_
# For VR listAssociatedVms to get list of VMs
if ($pg.GetInfo().Type -eq 'vr') {
$associatedVMs += @($pg.ListAssociatedVms() | Get-VIObjectByVIView)
}
# TODO test this: For ABR get VMs on GetProtectedDatastore
if ($pg.GetInfo().Type -eq 'san') {
$pds = @(Get-ProtectedDatastore -ProtectionGroup $pg)
$pds | ForEach-Object {
$ds = Get-Datastore -id $_.MoRef
$associatedVMs += @(Get-VM -Datastore $ds)
}
}
# get protected VMs
$protectedVmRefs += @(Get-ProtectedVM -ProtectionGroup $pg | ForEach-Object { $_.Vm.MoRef } | Select-Object -Unique)
}
# get associated but unprotected VMs
$associatedVMs | Where-Object { $protectedVmRefs -notcontains $_.ExtensionData.MoRef }
}
#Untested as I don't have ABR setup in my lab yet
<#
.SYNOPSIS
Get the subset of protected Datastores matching the input criteria
.PARAMETER ProtectionGroup
Return protected datastores associated with particular protection
groups
#>
Function Get-ProtectedDatastore {
[cmdletbinding()]
Param(
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup[]] $ProtectionGroup,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan[]] $RecoveryPlan,
[string] $ProtectionGroupName,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
if (-not $ProtectionGroup) {
$ProtectionGroup = Get-ProtectionGroup -Name $ProtectionGroupName -RecoveryPlan $RecoveryPlan -SrmServer $SrmServer
}
$ProtectionGroup | ForEach-Object {
$pg = $_
if ($pg.GetInfo().Type -eq 'san') { # only supported for array based replication datastores
$pg.ListProtectedDatastores()
}
}
}
#Untested as I don't have ABR setup in my lab yet
<#
.SYNOPSIS
Get the replicated datastores that aren't associated with a protection group.
#>
Function Get-ReplicatedDatastore {
[cmdletbinding()]
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
$api.Protection.ListUnassignedReplicatedDatastores()
}
<#
.SYNOPSIS
Protect a VM using SRM
.PARAMETER ProtectionGroup
The protection group that this VM will belong to
.PARAMETER Vm
The virtual machine to protect
#>
Function Protect-VM {
[cmdletbinding()]
Param(
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup] $ProtectionGroup,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $Vm,
[Parameter (ValueFromPipeline=$true)][VMware.Vim.VirtualMachine] $VmView
)
$moRef = Get_MoRefFromVmObj -Vm $Vm -VmView $VmView
$pgi = $ProtectionGroup.GetInfo()
#TODO query protection status first
if ($moRef) {
if ($pgi.Type -eq 'vr') {
$ProtectionGroup.AssociateVms(@($moRef))
}
$protectionSpec = New-Object VMware.VimAutomation.Srm.Views.SrmProtectionGroupVmProtectionSpec
$protectionSpec.Vm = $moRef
$protectTask = $ProtectionGroup.ProtectVms($protectionSpec)
while(-not $protectTask.IsComplete()) { Start-Sleep -Seconds 1 }
$protectTask.GetResult()
} else {
throw "Can't protect the VM, no MoRef found."
}
}
<#
.SYNOPSIS
Unprotect a VM using SRM
.PARAMETER ProtectionGroup
The protection group that this VM will be removed from
.PARAMETER Vm
The virtual machine to unprotect
#>
Function Unprotect-VM {
[cmdletbinding()]
Param(
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup] $ProtectionGroup,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $Vm,
[Parameter (ValueFromPipeline=$true)][VMware.Vim.VirtualMachine] $VmView,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectedVm] $ProtectedVm
)
$moRef = Get_MoRefFromVmObj -Vm $Vm -VmView $VmView -ProtectedVm $ProtectedVm
$pgi = $ProtectionGroup.GetInfo()
$protectTask = $ProtectionGroup.UnprotectVms($moRef)
while(-not $protectTask.IsComplete()) { Start-Sleep -Seconds 1 }
if ($pgi.Type -eq 'vr') {
$ProtectionGroup.UnassociateVms(@($moRef))
}
$protectTask.GetResult()
}
<#
.SYNOPSIS
Get a protection group folder
.PARAMETER SrmServer
The SRM Server to query for the protection group folder
#>
Function Get-ProtectionGroupFolder {
[cmdletbinding()]
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
$folder = $api.Protection.GetProtectionGroupRootFolder()
return $folder
}
<#
.SYNOPSIS
Create a new protection group
.PARAMETER Name
The name of the protection group
.PARAMETER Description
Description of the protection group
.PARAMETER Folder
The protection group folder in which to create the new protection group
.PARAMETER ArrayReplication
Set if protection group is for replicating VMs using Array based replication
.PARAMETER vSphereReplication
Set if protection group is for replicating VMs with vSphere Replication
.PARAMETER VMs
For vSphere Replication based protection, the VMs to add to the replication
group. These should already be replicated.
.PARAMETER VMViews
For vSphere Replication based protection, the VMs to add to the replication
group. These should already be replicated.
.PARAMETER SrmServer
The SRM Server to perform the operation against
#>
Function New-ProtectionGroup {
[cmdletbinding(DefaultParameterSetName="VR", SupportsShouldProcess=$True, ConfirmImpact="Medium")]
[OutputType([VMware.VimAutomation.Srm.Views.SrmProtectionGroup])]
Param(
[Parameter (Mandatory=$true)] $Name,
$Description,
[VMware.VimAutomation.Srm.Views.SrmProtectionGroupFolder] $Folder,
[Parameter (ParameterSetName="ABR", Mandatory=$true)][switch] $ArrayReplication,
[Parameter (ValueFromPipeline=$true, ParameterSetName="ABR")][VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.Datastore[]] $Datastores,
[Parameter (ValueFromPipeline=$true, ParameterSetName="ABR")][VMware.Vim.Datastore[]] $DatastoreViews,
[Parameter (ParameterSetName="VR", Mandatory=$true)][switch] $vSphereReplication,
[Parameter (ValueFromPipeline=$true, ParameterSetName="VR")][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]] $VMs,
[Parameter (ValueFromPipeline=$true, ParameterSetName="VR")][VMware.Vim.VirtualMachine[]] $VMViews,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$api = Get-ServerApiEndpoint $SrmServer
[VMware.VimAutomation.Srm.Views.SrmCreateProtectionGroupTask] $task = $null
#get root folder if this wasn't specified as a parameter
if(-not $Folder) {
$Folder = Get-ProtectionGroupFolder -SrmServer $SrmServer
}
if ($vSphereReplication) {
#create list of managed object references from VM and/or VM view arrays
[VMware.Vim.ManagedObjectReference[]]$moRefs = @()
foreach ($vm in $VMs) {
$moRefs += Get_MoRefFromVmObj -Vm $Vm
}
foreach ($VmView in $VMViews) {
$moRefs += Get_MoRefFromVmObj -VmView $VmView
}
if ($pscmdlet.ShouldProcess($Name, "New")) {
$task = $api.Protection.CreateHbrProtectionGroup($Folder.MoRef, $Name, $Description, $moRefs)
}
} elseif ($ArrayReplication) {
#create list of managed object references from VM and/or VM view arrays
$moRefs = @()
foreach ($ds in $Datastores) {
$moRefs += $ds.ExtensionData.MoRef
}
foreach ($DsView in $DatastoreViews) {
$moRefs += $DsView.MoRef
}
if ($pscmdlet.ShouldProcess($Name, "New")) {
$task = $api.Protection.CreateAbrProtectionGroup($Folder.MoRef, $Name, $Description, $moRefs)
}
} else {
throw "Undetermined protection group type"
}
# Complete task
while(-not $task.IsCreateProtectionGroupComplete()) { Start-Sleep -Seconds 1 }
# Retrieve the protection group, and protect associated VMs
$pg = $task.GetNewProtectionGroup()
if ($pg) {
$unProtectedVMs = Get-UnProtectedVM -ProtectionGroup $pg
$unProtectedVMs | Protect-VM -ProtectionGroup $pg
}
return $pg
}
<#
.SYNOPSIS
Delete a protection group
.PARAMETER ProtectionGroup
The protection group to remove
.PARAMETER SrmServer
The SRM Server to perform the operation against
#>
Function Remove-ProtectionGroup {
[cmdletbinding(SupportsShouldProcess=$True, ConfirmImpact="High")]
[OutputType([VMware.VimAutomation.Srm.Views.RemoveProtectionGroupTask])]
Param(
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup] $ProtectionGroup,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$api = Get-ServerApiEndpoint $SrmServer
[VMware.VimAutomation.Srm.Views.RemoveProtectionGroupTask] $task = $null
$pginfo = $ProtectionGroup.GetInfo()
if ($pscmdlet.ShouldProcess($pginfo.Name, "Remove")) {
$task = $api.Protection.RemoveProtectionGroup($ProtectionGroup.MoRef)
}
return $task
}
@@ -0,0 +1,556 @@
# SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
<#
.SYNOPSIS
Get the subset of recovery plans matching the input criteria
.PARAMETER Name
Return recovery plans matching the specified name
.PARAMETER ProtectionGroup
Return recovery plans associated with particular protection
groups
#>
Function Get-RecoveryPlan {
[cmdletbinding()]
Param(
[Parameter(position=1)][string] $Name,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup[]] $ProtectionGroup,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
begin {
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
$rps = @()
}
process {
if ($ProtectionGroup) {
foreach ($pg in $ProtectionGroup) {
$rps += $pg.ListRecoveryPlans()
}
$rps = Select_UniqueByMoRef($rps)
} else {
$rps += $api.Recovery.ListPlans()
}
}
end {
$rps | ForEach-Object {
$rp = $_
$rpi = $rp.GetInfo()
$selected = (-not $Name -or ($Name -eq $rpi.Name))
if ($selected) {
Add-Member -InputObject $rp -MemberType NoteProperty -Name "Name" -Value $rpi.Name
$rp
}
}
}
}
<#
.SYNOPSIS
Start a Recovery Plan action like test, recovery, cleanup, etc.
.PARAMETER RecoveryPlan
The recovery plan to start
.PARAMETER RecoveryMode
The recovery mode to invoke on the plan. May be one of "Test", "Cleanup", "Failover", "Migrate", "Reprotect"
#>
Function Start-RecoveryPlan {
[cmdletbinding(SupportsShouldProcess=$True, ConfirmImpact="High")]
Param(
[Parameter (Mandatory=$true, ValueFromPipeline=$true, Position=1)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
[VMware.VimAutomation.Srm.Views.SrmRecoveryPlanRecoveryMode] $RecoveryMode = [VMware.VimAutomation.Srm.Views.SrmRecoveryPlanRecoveryMode]::Test,
[bool] $SyncData = $True
)
# Validate with informative error messages
$rpinfo = $RecoveryPlan.GetInfo()
# Create recovery options
$rpOpt = New-Object VMware.VimAutomation.Srm.Views.SrmRecoveryOptions
$rpOpt.SyncData = $SyncData
# Prompt the user to confirm they want to execute the action
if ($pscmdlet.ShouldProcess($rpinfo.Name, $RecoveryMode)) {
if ($rpinfo.State -eq 'Protecting') {
throw "This recovery plan action needs to be initiated from the other SRM instance"
}
$RecoveryPlan.Start($RecoveryMode, $rpOpt)
}
}
<#
.SYNOPSIS
Stop a running Recovery Plan action.
.PARAMETER RecoveryPlan
The recovery plan to stop
#>
Function Stop-RecoveryPlan {
[cmdletbinding(SupportsShouldProcess=$True,ConfirmImpact="High")]
Param(
[Parameter (Mandatory=$true, ValueFromPipeline=$true, Position=1)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan
)
# Validate with informative error messages
$rpinfo = $RecoveryPlan.GetInfo()
# Prompt the user to confirm they want to cancel the running action
if ($pscmdlet.ShouldProcess($rpinfo.Name, 'Cancel')) {
$RecoveryPlan.Cancel()
}
}
<#
.SYNOPSIS
Retrieve the historical results of a recovery plan
.PARAMETER RecoveryPlan
The recovery plan to retrieve the history for
#>
Function Get-RecoveryPlanResult {
[cmdletbinding()]
Param(
[Parameter (Mandatory=$true, ValueFromPipeline=$true, Position=1)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
[VMware.VimAutomation.Srm.Views.SrmRecoveryPlanRecoveryMode] $RecoveryMode,
[VMware.VimAutomation.Srm.Views.SrmRecoveryResultResultState] $ResultState,
[DateTime] $StartedAfter,
[DateTime] $startedBefore,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
# Get the history objects
$history = $api.Recovery.GetHistory($RecoveryPlan.MoRef)
$resultCount = $history.GetResultCount()
if ($resultCount -gt 0) {
$results = $history.GetRecoveryResult($resultCount)
$results |
Where-Object { -not $RecoveryMode -or $_.RunMode -eq $RecoveryMode } |
Where-Object { -not $ResultState -or $_.ResultState -eq $ResultState } |
Where-Object { $null -eq $StartedAfter -or $_.StartTime -gt $StartedAfter } |
Where-Object { $null -eq $StartedBefore -or $_.StartTime -lt $StartedBefore }
}
}
<#
.SYNOPSIS
Exports a recovery plan result object to XML format
.PARAMETER RecoveryPlanResult
The recovery plan result to export
#>
Function Export-RecoveryPlanResultAsXml {
[cmdletbinding()]
[OutputType([xml])]
Param(
[Parameter (Mandatory=$true, ValueFromPipeline=$true, Position=1)][VMware.VimAutomation.Srm.Views.SrmRecoveryResult] $RecoveryPlanResult,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
$RecoveryPlan = $RecoveryPlanResult.Plan
$history = $api.Recovery.GetHistory($RecoveryPlan.MoRef)
$lines = $history.GetResultLength($RecoveryPlanResult.Key)
[xml] $history.RetrieveStatus($RecoveryPlanResult.Key, 0, $lines)
}
<#
.SYNOPSIS
Add a protection group to a recovery plan. This requires SRM 5.8 or later.
.PARAMETER RecoveryPlan
The recovery plan the protection group will be associated with
.PARAMETER ProtectionGroup
The protection group to associate with the recovery plan
#>
Function Add-ProtectionGroupToRecoveryPlan {
[cmdletbinding()]
Param(
[Parameter (Mandatory=$true, Position=1)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
[Parameter (Mandatory=$true, ValueFromPipeline=$true, Position=2)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup] $ProtectionGroup
)
if ($RecoveryPlan -and $ProtectionGroup) {
foreach ($pg in $ProtectionGroup) {
try {
$RecoveryPlan.AddProtectionGroup($pg.MoRef)
} catch {
Write-Error $_
}
}
}
}
<#
.SYNOPSIS
Remove a protection group to a recovery plan. This requires SRM 6.5 or later.
.PARAMETER RecoveryPlan
The recovery plan the protection group will be disassociated from
.PARAMETER ProtectionGroup
The protection group to disassociate from the recovery plan
#>
Function Remove-ProtectionGroupFromRecoveryPlan {
[cmdletbinding()]
Param(
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroup] $ProtectionGroup
)
if ($RecoveryPlan -and $ProtectionGroup) {
foreach ($pg in $ProtectionGroup) {
try {
$RecoveryPlan.RemoveProtectionGroupFromRecoveryPlan($pg.MoRef)
} catch {
Write-Error $_
}
}
}
}
<#
.SYNOPSIS
Get the recovery settings of a protected VM. This requires SRM 5.8 or later.
.PARAMETER RecoveryPlan
The recovery plan the settings will be retrieved from.
.PARAMETER Vm
The virtual machine to retieve recovery settings for.
#>
Function Get-RecoverySetting {
[cmdletbinding()]
Param(
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $Vm,
[Parameter (ValueFromPipeline=$true)][VMware.Vim.VirtualMachine] $VmView,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectedVm] $ProtectedVm
)
$moRef = Get_MoRefFromVmObj -Vm $Vm -VmView $VmView -ProtectedVm $ProtectedVm
if ($RecoveryPlan -and $moRef) {
$RecoveryPlan.GetRecoverySettings($moRef)
}
}
<#
.SYNOPSIS
Get the recovery settings of a protected VM. This requires SRM 5.8 or later.
.PARAMETER RecoveryPlan
The recovery plan the settings will be retrieved from.
.PARAMETER Vm
The virtual machine to configure recovery settings on.
.PARAMETER RecoverySettings
The recovery settings to configure. These should have been retrieved via a
call to Get-RecoverySettings
#>
Function Set-RecoverySetting {
[cmdletbinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")]
Param(
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $Vm,
[Parameter (ValueFromPipeline=$true)][VMware.Vim.VirtualMachine] $VmView,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectedVm] $ProtectedVm,
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings
)
$moRef = Get_MoRefFromVmObj -Vm $Vm -VmView $VmView -ProtectedVm $ProtectedVm
if ($RecoveryPlan -and $moRef -and $RecoverySettings) {
if ($PSCmdlet.ShouldProcess("$moRef", "Set")) {
$RecoveryPlan.SetRecoverySettings($moRef, $RecoverySettings)
}
}
}
<#
.SYNOPSIS
Create a new per-Vm command to add to the SRM Recovery Plan
.PARAMETER Command
The command script to execute.
.PARAMETER Description
The user friendly description of this script.
.PARAMETER Timeout
The number of seconds this command has to execute before it will be timedout.
.PARAMETER RunInRecoveredVm
For a post-power on command this flag determines whether it will run on the
recovered VM or on the SRM server.
#>
Function New-Command {
[cmdletbinding(SupportsShouldProcess=$true, ConfirmImpact="None")]
Param(
[Parameter (Mandatory=$true)][string] $Command,
[Parameter (Mandatory=$true)][string] $Description,
[int] $Timeout = 300,
[switch] $RunInRecoveredVm = $false
)
if($PSCmdlet.ShouldProcess("Description", "New")) {
$srmWsdlCmd = New-Object VMware.VimAutomation.Srm.WsdlTypes.SrmCommand
$srmCmd = New-Object VMware.VimAutomation.Srm.Views.SrmCommand -ArgumentList $srmWsdlCmd
$srmCmd.Command = $Command
$srmCmd.Description = $Description
$srmCmd.RunInRecoveredVm = $RunInRecoveredVm
$srmCmd.Timeout = $Timeout
$srmCmd.Uuid = [guid]::NewGuid()
return $srmCmd
}
}
<# Internal function #>
Function Add_Command {
[cmdletbinding()]
Param(
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings,
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmCommand] $SrmCommand,
[Parameter (Mandatory=$true)][bool] $PostRecovery
)
if ($PostRecovery) {
$commands = $RecoverySettings.PostPowerOnCallouts
} else {
$commands = $RecoverySettings.PrePowerOnCallouts
}
if (-not $commands) {
$commands = New-Object System.Collections.Generic.List[VMware.VimAutomation.Srm.Views.SrmCallout]
}
$commands.Add($SrmCommand)
if ($PostRecovery) {
$RecoverySettings.PostPowerOnCallouts = $commands
} else {
$RecoverySettings.PrePowerOnCallouts = $commands
}
}
<#
.SYNOPSIS
Add an SRM command to the set of pre recovery callouts for a VM.
.PARAMETER RecoverySettings
The recovery settings to update. These should have been retrieved via a
call to Get-RecoverySettings
.PARAMETER SrmCommand
The command to add to the list.
#>
Function Add-PreRecoveryCommand {
[cmdletbinding()]
[OutputType([VMware.VimAutomation.Srm.Views.SrmRecoverySettings])]
Param(
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings,
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmCommand] $SrmCommand
)
Add_Command -RecoverySettings $RecoverySettings -SrmCommand $SrmCommand -PostRecovery $false
return $RecoverySettings
}
<#
.SYNOPSIS
Remove an SRM command from the set of pre recovery callouts for a VM.
.PARAMETER RecoverySettings
The recovery settings to update. These should have been retrieved via a
call to Get-RecoverySettings
.PARAMETER SrmCommand
The command to remove from the list.
#>
Function Remove-PreRecoveryCommand {
[cmdletbinding(SupportsShouldProcess=$true, ConfirmImpact="Low")]
[OutputType([VMware.VimAutomation.Srm.Views.SrmRecoverySettings])]
Param(
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings,
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmCommand] $SrmCommand
)
if ($pscmdlet.ShouldProcess($SrmCommand.Description, "Remove")) {
$RecoverySettings.PrePowerOnCallouts.Remove($SrmCommand)
}
return $RecoverySettings
}
<#
.SYNOPSIS
Add an SRM command to the set of post recovery callouts for a VM.
.PARAMETER RecoverySettings
The recovery settings to update. These should have been retrieved via a
call to Get-RecoverySettings
.PARAMETER SrmCommand
The command to add to the list.
#>
Function Add-PostRecoveryCommand {
[cmdletbinding()]
[OutputType([VMware.VimAutomation.Srm.Views.SrmRecoverySettings])]
Param(
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings,
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmCommand] $SrmCommand
)
Add_Command -RecoverySettings $RecoverySettings -SrmCommand $SrmCommand -PostRecovery $true
return $RecoverySettings
}
<#
.SYNOPSIS
Remove an SRM command from the set of post recovery callouts for a VM.
.PARAMETER RecoverySettings
The recovery settings to update. These should have been retrieved via a
call to Get-RecoverySettings
.PARAMETER SrmCommand
The command to remove from the list.
#>
Function Remove-PostRecoveryCommand {
[cmdletbinding(SupportsShouldProcess=$true, ConfirmImpact="Low")]
[OutputType([VMware.VimAutomation.Srm.Views.SrmRecoverySettings])]
Param(
[Parameter (Mandatory=$true, ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmRecoverySettings] $RecoverySettings,
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmCommand] $SrmCommand
)
if ($pscmdlet.ShouldProcess($SrmCommand.Description, "Remove")) {
$RecoverySettings.PostPowerOnCallouts.Remove($SrmCommand)
}
return $RecoverySettings
}
<#
.SYNOPSIS
Create a new recovery plan
.PARAMETER Name
The name for this recovery plan
.PARAMETER Description
A description of the recovery plan
.PARAMETER Folder
The recovery plan folder in which to create this recovery plan. Will default to
the root recovery plan folder
.PARAMETER ProtectionGroups
The protection groups to associate with this recovery plan
.PARAMETER TestNetworkMappings
The test network mappings to configure as part of this recovery plan
.PARAMETER SrmServer
The SRM Server to operate against
#>
Function New-RecoveryPlan {
[cmdletbinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")]
Param(
[Parameter (Mandatory=$true)][string] $Name,
[string] $Description,
[VMware.VimAutomation.Srm.Views.SrmRecoveryPlanFolder] $Folder,
[VMware.VimAutomation.Srm.Views.SrmProtectionGroup[]] $ProtectionGroups,
[VMware.VimAutomation.Srm.Views.SrmRecoveryTestNetworkMapping[]] $TestNetworkMappings,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
if (-not $Folder) {
$Folder = Get-RecoveryPlanFolder -SrmServer $SrmServer
}
$protectionGroupmRefs += @( $ProtectionGroups | ForEach-Object { $_.MoRef } | Select-Object -Unique)
[VMware.VimAutomation.Srm.Views.CreateRecoveryPlanTask] $task = $null
if ($PSCmdlet.ShouldProcess($Name, "New")) {
$task = $api.Recovery.CreateRecoveryPlan(
$Name,
$Folder.MoRef,
$protectionGroupmRefs,
$Description,
$TestNetworkMappings
)
}
while(-not $task.IsCreateRecoveryPlanComplete()) { Start-Sleep -Seconds 1 }
$task.GetNewRecoveryPlan()
}
<#
.SYNOPSIS
Remove a recovery plan permanently
.PARAMETER RecoveryPlan
The recovery plan to remove
.PARAMETER SrmServer
The SRM Server to operate against
#>
Function Remove-RecoveryPlan {
[cmdletbinding(SupportsShouldProcess=$True, ConfirmImpact="High")]
Param(
[Parameter (Mandatory=$true)][VMware.VimAutomation.Srm.Views.SrmRecoveryPlan] $RecoveryPlan,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
$rpinfo = $RecoveryPlan.GetInfo()
if ($pscmdlet.ShouldProcess($rpinfo.Name, "Remove")) {
$api.Recovery.DeleteRecoveryPlan($RecoveryPlan.MoRef)
}
}
<#
.SYNOPSIS
Get a recovery plan folder
.PARAMETER SrmServer
The SRM Server to query for the recovery plan folder
#>
Function Get-RecoveryPlanFolder {
[cmdletbinding()]
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
$folder = $api.Recovery.GetRecoveryPlanRootFolder()
return $folder
}
@@ -0,0 +1,24 @@
# SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
<#
.SYNOPSIS
Trigger Discover Devices for Site Recovery Manager
.OUTPUTS
Returns discover devices task
#>
Function Start-DiscoverDevice {
[cmdletbinding(SupportsShouldProcess=$True, ConfirmImpact="Medium")]
[OutputType([VMware.VimAutomation.Srm.Views.DiscoverDevicesTask])]
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$api = Get-ServerApiEndpoint -SrmServer $SrmServer
$name = $SrmServer.Name
[VMware.VimAutomation.Srm.Views.DiscoverDevicesTask] $task = $null
if ($pscmdlet.ShouldProcess($name, "Rescan Storage Devices")) {
$task = $api.Storage.DiscoverDevices()
}
return $task
}
@@ -0,0 +1,92 @@
#
# Module manifest for module 'Meadowcroft.Srm'
#
@{
# Script module or binary module file associated with this manifest.
RootModule = 'Meadowcroft.Srm.psm1'
# Version number of this module.
ModuleVersion = '0.2'
# ID used to uniquely identify this module
GUID = 'f9247009-9168-4a21-831b-819f82884ffe'
# Author of this module
Author = 'Ben Meadowcroft'
# Company or vendor of this module
CompanyName = 'VMware, Inc'
# Copyright statement for this module
Copyright = '(c) 2014 - 2017. All rights reserved.'
# Description of the functionality provided by this module
# Description = ''
# Minimum version of the Windows PowerShell engine required by this module
# PowerShellVersion = ''
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of Microsoft .NET Framework required by this module
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @{ModuleName='VMware.VimAutomation.Srm'; ModuleVersion='6.5'}
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
NestedModules = 'Meadowcroft.Srm.Recovery.ps1','Meadowcroft.Srm.Protection.ps1','Meadowcroft.Srm.Storage.ps1'
# NestedModules = @()
# Functions to export from this module, note that internal functions use '_' not '-' as separator
FunctionsToExport = '*-*'
# Cmdlets to export from this module
CmdletsToExport = '*'
# Variables to export from this module
VariablesToExport = '*'
# Aliases to export from this module
AliasesToExport = '*'
# List of all modules packaged with this module
# ModuleList = @()
# List of all files packaged with this module
# FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
DefaultCommandPrefix = 'Srm'
}
@@ -0,0 +1,148 @@
# SRM Helper Methods - https://github.com/benmeadowcroft/SRM-Cmdlets
<#
.SYNOPSIS
This is intended to be an "internal" function only. It filters a
pipelined input of objects and elimiates duplicates as identified
by the MoRef property on the object.
.LINK
https://github.com/benmeadowcroft/SRM-Cmdlets/
#>
Function Select_UniqueByMoRef {
Param(
[Parameter (ValueFromPipeline=$true)] $in
)
process {
$moref = New-Object System.Collections.ArrayList
$in | Sort-Object | Select-Object MoRef -Unique | ForEach-Object { $moref.Add($_.MoRef) } > $null
$in | ForEach-Object {
if ($_.MoRef -in $moref) {
$moref.Remove($_.MoRef)
$_ #output
}
}
}
}
<#
.SYNOPSIS
This is intended to be an "internal" function only. It gets the
MoRef property of a VM from either a VM object, a VM view, or the
protected VM object.
#>
Function Get_MoRefFromVmObj {
Param(
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $Vm,
[Parameter (ValueFromPipeline=$true)][VMware.Vim.VirtualMachine] $VmView,
[Parameter (ValueFromPipeline=$true)][VMware.VimAutomation.Srm.Views.SrmProtectionGroupProtectedVm] $ProtectedVm
)
$moRef = $null
if ($Vm.ExtensionData.MoRef) { # VM object
$moRef = $Vm.ExtensionData.MoRef
} elseif ($VmView.MoRef) { # VM view
$moRef = $VmView.MoRef
} elseif ($protectedVm) {
$moRef = $ProtectedVm.Vm.MoRef
}
$moRef
}
<#
.SYNOPSIS
Lookup the srm instance for a specific server.
#>
Function Get-Server {
[cmdletbinding()]
Param(
[string] $SrmServerAddress,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$found = $null
if ($SrmServer) {
$found = $SrmServer
} elseif ($SrmServerAddress) {
# search for server address in default servers
$global:DefaultSrmServers | ForEach-Object {
if ($_.Name -ieq $SrmServerAddress) {
$found = $_
}
}
if (-not $found) {
throw "SRM server $SrmServerAddress not found. Connect-Server must be called first."
}
}
if (-not $found) {
#default result
$found = $global:DefaultSrmServers[0]
}
return $found;
}
<#
.SYNOPSIS
Retrieve the SRM Server Version
#>
Function Get-ServerVersion {
[cmdletbinding()]
Param(
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
$srm = Get-Server $SrmServer
$srm.Version
}
<#
.SYNOPSIS
Lookup the SRM API endpoint for a specific server.
#>
Function Get-ServerApiEndpoint {
[cmdletbinding()]
Param(
[string] $SrmServerAddress,
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $SrmServer
)
[VMware.VimAutomation.Srm.Types.V1.SrmServer] $server = Get-Server -SrmServerAddress $SrmServerAddress -SrmServer $SrmServer
return $server.ExtensionData
}
<#
.SYNOPSIS
Get the placeholder VMs that are associated with SRM
#>
Function Get-PlaceholderVM {
[cmdletbinding()]
Param()
Get-VM @Args | Where-Object {$_.ExtensionData.Config.ManagedBy.extensionKey -like "com.vmware.vcDr*" -and $_.ExtensionData.Config.ManagedBy.Type -ieq 'placeholderVm'}
}
<#
.SYNOPSIS
Get the test VMs that are associated with SRM
#>
Function Get-TestVM {
[cmdletbinding()]
Param()
Get-VM @Args | Where-Object {$_.ExtensionData.Config.ManagedBy.extensionKey -like "com.vmware.vcDr*" -and $_.ExtensionData.Config.ManagedBy.Type -ieq 'testVm'}
}
<#
.SYNOPSIS
Get the VMs that are replicated using vSphere Replication. These may not be SRM
protected VMs.
#>
Function Get-ReplicatedVM {
[cmdletbinding()]
Param()
Get-VM @Args | Where-Object {($_.ExtensionData.Config.ExtraConfig | Where-Object { $_.Key -eq 'hbr_filter.destination' -and $_.Value } )}
}
@@ -0,0 +1,7 @@
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
This product is licensed to you under the Apache License version 2.0 (the "License"). You may not use this product except in compliance with the License.
This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
@@ -0,0 +1,81 @@
# SRM PowerCLI Cmdlets
Helper functions for working with VMware SRM 6.5 with PowerCLI 6.5.1 or later. PowerShell 5.0 and above is required.
This module is provided for illustrative/educational purposes to explain how the PowerCLI access to the SRM public API can be used.
## Getting Started
### Getting the SRM cmdlets
The latest version of the software can be cloned from the git repository:
git clone https://github.com/benmeadowcroft/SRM-Cmdlets.git
Or downloaded as a [zip file](https://github.com/benmeadowcroft/SRM-Cmdlets/archive/master.zip).
Specific releases (compatible with earlier PowerCLI and SRM versions) can be downloaded via the [release page](https://github.com/benmeadowcroft/SRM-Cmdlets/releases).
### Deploy SRM-Cmdlets module
After cloning (or downloading and extracting) the PowerShell module, you can import the module into your current PowerShell session by by passing the path to `Meadowcroft.Srm.psd1` to the `Import-Module` cmdlet, e.g.:
Import-Module -Name .\SRM-Cmdlets\Meadowcroft.Srm.psd1
You can also install the module into the PowerShell path so it can be loaded implicitly. See [Microsoft's Installing Modules instructions](http://msdn.microsoft.com/en-us/library/dd878350) for more details on how to do this.
The module uses the default prefix of `Srm` for the custom functions it defines. This can be overridden when importing the module by setting the value of the `-Prefix` parameter when calling `Import-Module`.
### Connecting to SRM
After installing the module the next step is to connect to the SRM server. Details of how to do this are located in the [PowerCLI 6.5.1 User's Guide](http://pubs.vmware.com/vsphere-65/topic/com.vmware.powercli.ug.doc/GUID-A5F206CF-264D-4565-8CB9-4ED1C337053F.html)
$credential = Get-Credential
Connect-VIServer -Server vc-a.example.com -Credential $credential
Connect-SrmServer -Credential $credential -RemoteCredential $credential
At this point we've just been using the cmdlets provided by PowerCLI, the PowerCLI documentation also provides some examples of how to call the SRM API to perform various tasks. In the rest of this introduction we'll perform some of those tasks using the custom functions defined in this project.
### Report the Protected Virtual Machines and Their Protection Groups
Goal: Create a simple report listing the VMs protected by SRM and the protection group they belong to.
Get-SrmProtectionGroup | %{
$pg = $_
Get-SrmProtectedVM -ProtectionGroup $pg } | %{
$output = "" | select VmName, PgName
$output.VmName = $_.Vm.Name
$output.PgName = $pg.GetInfo().Name
$output
} | Format-Table @{Label="VM Name"; Expression={$_.VmName} },
@{Label="Protection group name"; Expression={$_.PgName}
}
### Report the Last Recovery Plan Test
Goal: Create a simple report listing the state of the last test of a recovery plan
Get-SrmRecoveryPlan | %{ $_ |
Get-SrmRecoveryPlanResult -RecoveryMode Test | select -First 1
} | Select Name, StartTime, RunMode, ResultState | Format-Table
### Execute a Recovery Plan Test
Goal: for a specific recovery plan, execute a test failover. Note the "local" SRM server we are connected to should be the recovery site in order for this to be successful.
Get-SrmRecoveryPlan -Name "Name of Plan" | Start-SrmRecoveryPlan -RecoveryMode Test
### Export the Detailed XML Report of the Last Recovery Plan Workflow
Goal: get the XML report of the last recovery plan execution for a specific recovery plan.
Get-SrmRecoveryPlan -Name "Name of Plan" | Get-SrmRecoveryPlanResult |
select -First 1 | Export-SrmRecoveryPlanResultAsXml
### Protect a Replicated VM
Goal: Take a VM replicated using vSphere Replication or Array Based Replication, add it to an appropriate protection group and configure it for protection
$pg = Get-SrmProtectionGroup "Name of Protection Group"
Get-VM vm-01a | Protect-SrmVM -ProtectionGroup $pg
+33
View File
@@ -0,0 +1,33 @@
$VMHostFQDNs = @(
'itdvmmdntest07.nd.gov'
)
foreach ($VMHostFQDN in $VMHostFQDNs) {
$VMHostName = $VMHostFQDN.Split('.')[0]
#$CmdbCi = Get-ITDServiceNowRecord -Table cmdb_ci_server -Filter "name=$VMHostName"
$NewITDServiceNowChangeRequestParams = @{
RequestedByUsername = 'zmeier';
#ConfigurationItemSysId = $CmdbCi.sys_id;
Category = 'Systems Platforms - Systems';
Subcategory = 'VMware';
Impact = 2;
Priority = 2;
ShortDescription = "Upgrade $VMHostFQDN to vSphere 8.0 U3f, installing prerequisite firmware updates HPE Synergy 2025.05.01";
Description = "Upgrade $VMHostFQDN to vSphere 8.0 U3f, remediation for VMSA-2025-0013";
Justification = "Firmware updates. Security updates. Bug fixes.";
Implementation = "Evacuate all VMs from $VMHostFQDN. Install new firmware version 2025.05.01. Upgrade vSphere to 8.0 U3f. Apply VMware Host Profiles";
RiskImpactAnalysis = "Low, Running virtual machines will be evacuated before update process begins.";
BackoutPlan = "If the upgrade fails, revert to previous firmware version and vSphere version through manual process.";
TestPlan = "Sandbox environment has been tested with this upgrade. No issues were found.";
WhoIsImpacted = "";
StartTime = (Get-Date -Year 2025 -Month 11 -Day 7)
EndTime = (Get-Date -Year 2025 -Month 11 -Day 7).AddHours(8);
AssignmentGroup = 'NDIT-Computer Systems Windows';
ChangeManagerUsername = 'khellman';
ChangeCoordinatorUsername = 'mlaverdure';
AssignedToUsername = 'zmeier';
}
$CHG = New-ITDServiceNowChangeRequest @NewITDServiceNowChangeRequestParams
}
+65
View File
@@ -0,0 +1,65 @@
$Month = 7
26..26 | ForEach-Object {
$Records = [System.Collections.ArrayList]@()
Write-Warning $_
$StartDate = Get-Date -Year 2023 -Month $Month -Day $_ -Hour 0 -Minute 0 -Second 0
$EndDate = Get-Date -Year 2023 -Month $Month -Day $_ -Hour 23 -Minute 59 -Second 59
$filter = @('cat_item', '-eq', '89efc7041bb41dd04d8943b1b24bcb63'),
'-and',
@('opened_at', '-gt', $StartDate ),
'-and',
@('opened_at', '-lt', $EndDate )
$x = Get-ServiceNowRecord -Table 'Requested Item' -Filter $Filter -IncludeTotalCount -IncludeCustomVariable
ForEach ($z in $x) {
$obj = [PSCustomObject]@{
'number' = $z.number;
'sys_id' = $z.sys_id;
'opened_at' = $z.opened_at;
'requested_for' = $z.requested_for.display_value;
'request_type' = ($z.CustomVariable | Where-Object Name -EQ 'request_type').Value
'application_name' = ($z.CustomVariable | Where-Object Name -EQ 'application_name').Value
'environment' = ($z.CustomVariable | Where-Object Name -EQ 'environment').Value
'additional_comments' = ($z.CustomVariable | Where-Object Name -EQ 'additional_comments').Value
'vm_work_needed' = ($z.CustomVariable | Where-Object Name -EQ 'vm_work_needed').Value
'server_name' = ($z.CustomVariable | Where-Object Name -EQ 'server_name').Value
'host_name' = ($z.CustomVariable | Where-Object Name -EQ 'host_name').Value
'server_type' = ($z.CustomVariable | Where-Object Name -EQ 'server_type').Value
'operating_system' = ($z.CustomVariable | Where-Object Name -EQ 'operating_system').Value
'target_platform' = ($z.CustomVariable | Where-Object Name -EQ 'target_platform').Value
'processors' = ($z.CustomVariable | Where-Object Name -EQ 'processors').Value
'memory_gb' = ($z.CustomVariable | Where-Object Name -EQ 'memory_gb').Value
'cidr_block' = ($z.CustomVariable | Where-Object Name -EQ 'cidr_block').Value
'data_center' = ($z.CustomVariable | Where-Object Name -EQ 'data_center').Value
'licensing_restrictions' = ($z.CustomVariable | Where-Object Name -EQ 'licensing_restrictions').Value
'agency_name' = ($z.CustomVariable | Where-Object Name -EQ 'agency_name').Value
'application_info' = ($z.CustomVariable | Where-Object Name -EQ 'application_info').Value
'support_hours' = ($z.CustomVariable | Where-Object Name -EQ 'support_hours').Value
'dr_protection' = ($z.CustomVariable | Where-Object Name -EQ 'dr_protection').Value
'startup_priority' = ($z.CustomVariable | Where-Object Name -EQ 'startup_priority').Value
'disk_1_os' = ($z.CustomVariable | Where-Object Name -EQ 'disk_1_os').Value
'disk_2_swap_disk' = ($z.CustomVariable | Where-Object Name -EQ 'disk_2_swap_disk').Value
'disk_3' = ($z.CustomVariable | Where-Object Name -EQ 'disk_3').Value
'disk_4' = ($z.CustomVariable | Where-Object Name -EQ 'disk_4').Value
'disk_5' = ($z.CustomVariable | Where-Object Name -EQ 'disk_5').Value
'disk_6' = ($z.CustomVariable | Where-Object Name -EQ 'disk_6').Value
'disk_7' = ($z.CustomVariable | Where-Object Name -EQ 'disk_7').Value
'disk_8' = ($z.CustomVariable | Where-Object Name -EQ 'disk_8').Value
'disk_9' = ($z.CustomVariable | Where-Object Name -EQ 'disk_9').Value
'disk_10' = ($z.CustomVariable | Where-Object Name -EQ 'disk_10').Value
'disk_11' = ($z.CustomVariable | Where-Object Name -EQ 'disk_11').Value
'disk_12' = ($z.CustomVariable | Where-Object Name -EQ 'disk_12').Value
'disk_13' = ($z.CustomVariable | Where-Object Name -EQ 'disk_13').Value
'disk_14' = ($z.CustomVariable | Where-Object Name -EQ 'disk_14').Value
'disk_15' = ($z.CustomVariable | Where-Object Name -EQ 'disk_15').Value
'disk_16' = ($z.CustomVariable | Where-Object Name -EQ 'disk_16').Value
}
$null = $Records.Add($obj)
}
#$Records = $Records
If ($Records) { $Records | Export-Csv "D:\OneDrive - State of North Dakota\RITMexport.csv" -Append -NoTypeInformation }
}
+10
View File
@@ -0,0 +1,10 @@
$Filter = 'requested_for=206d9e091b8898102653997fbd4bcbd4^ORrequested_for=1c1d16451b8898102653997fbd4bcb3b^ORrequested_for=2ddc5a811b8898102653997fbd4bcb3a^ORrequested_for=920d9e051b8898102653997fbd4bcb10^ORrequested_for=20287f77dbe0a8106f6ae415ca9619c7^ORrequested_for=e65fe8581b9518902653997fbd4bcb90^ORrequested_for=c74d5ec51b8898102653997fbd4bcb27^ORrequested_for=e74d9ec51b8898102653997fbd4bcbd1^ORrequested_for=fa7dde491b8898102653997fbd4bcbf0^ORrequested_for=fdad9e891b8898102653997fbd4bcbe2^ORrequested_for=d6adde891b8898102653997fbd4bcb7c^ORrequested_for=d62d52851b8898102653997fbd4bcba4^ORrequested_for=0ace50ad976f11d49ff29c14a253afc5^ORrequested_for=518dd2891b8898102653997fbd4bcb19^ORrequested_for=733d92c51b8898102653997fbd4bcbf7^cat_item=fc32b5ce1bba5cd02045fd16dc4bcb47'
$x = Get-ITDServiceNowRecord -ItemType 'Request Item' -Filter $Filter -IncludeTotalCount -Verbose -IncludeCustomVariable
#$x[0] | Select-Object Number, @{n='RequestedBy';e={(Get-ITDServiceNowUser -SysId $_.v_requested_by.value).Name}}, opened_at, closed_at, user_id
$x | Select-Object Number, @{n='RequestedFor';e={(Get-ITDServiceNowUser -SysId $_.requested_for.value).Name}}, @{n='v_type';e={$_.customvariable.v_type.value}}, opened_at, closed_at, @{n='user_id';e={$_.customvariable.user_id.value}} -ov z
$z| export-csv "D:\ADServiceAccountHistory.csv"
+94
View File
@@ -0,0 +1,94 @@
$CurrentCsv = Import-Csv -Path "D:\OneDrive - State of North Dakota\RitmExportAppServer.csv"
$NewestRecord = $CurrentCsv | Sort-Object -Descending number | select -First 1
[datetime]$StartDate = $NewestRecord.opened_at
#$StartDate = Get-date -Year 2020 -Month 1 -Day 1
[datetime]$EndDate = Get-Date #-Year 2023 -Month 3 -Day 30
$filter = @('cat_item', '-eq', '89efc7041bb41dd04d8943b1b24bcb63'),
'-and',
@('opened_at', '-gt', $StartDate ),
'-and',
@('opened_at', '-lt', $EndDate )
$RecordSearch = Get-ServiceNowRecord -Table 'Requested Item' -Filter $Filter -IncludeTotalCount | Sort-Object Number
#$RecordSearch = Get-ServiceNowRecord -Table 'Requested Item' -number RITM0245487
$CurrentCsv = Import-Csv -Path "D:\OneDrive - State of North Dakota\RitmExportAppServer.csv"
ForEach ($Record in $RecordSearch) {
Write-Warning -Message ("Begin record " + $Record.number)
If ( @($CurrentCsv.number | where-object {$_ -eq $Record.Number}).count -gt 0) {
Write-Warning -Message ("Number " + $Record.Number + " already in csv")
# do nothing
}
Else {
#Write-Warning -Message $record.number
$RecordDetail = Get-ServiceNowRecord -Table 'Requested Item' -ID $Record.Number -IncludeCustomVariable
ForEach ($Record in $RecordDetail) {
$RecordsToExport = [System.Collections.ArrayList]@()
$obj = [PSCustomObject][ordered]@{
'number' = $Record.number;
'sys_id' = $Record.sys_id;
'opened_at' = $Record.opened_at;
'requested_for' = $Record.requested_for.display_value;
'short_description' = $Record.short_description;
'request_type' = ($Record.CustomVariable | Where-Object Name -EQ 'request_type').Value
'application_name' = ($Record.CustomVariable | Where-Object Name -EQ 'application_name').Value
'environment' = ($Record.CustomVariable | Where-Object Name -EQ 'environment').Value
'additional_comments' = ($Record.CustomVariable | Where-Object Name -EQ 'additional_comments').Value
'vm_work_needed' = ($Record.CustomVariable | Where-Object Name -EQ 'vm_work_needed').Value
'server_name' = ($Record.CustomVariable | Where-Object Name -EQ 'server_name').Value
'host_name' = ($Record.CustomVariable | Where-Object Name -EQ 'host_name').Value
'server_type' = ($Record.CustomVariable | Where-Object Name -EQ 'server_type').Value
'operating_system' = ($Record.CustomVariable | Where-Object Name -EQ 'operating_system').Value
'target_platform' = ($Record.CustomVariable | Where-Object Name -EQ 'target_platform').Value
'processors' = ($Record.CustomVariable | Where-Object Name -EQ 'processors').Value
'memory_gb' = ($Record.CustomVariable | Where-Object Name -EQ 'memory_gb').Value
'cidr_block' = ($Record.CustomVariable | Where-Object Name -EQ 'cidr_block').Value
'data_center' = ($Record.CustomVariable | Where-Object Name -EQ 'data_center').Value
'licensing_restrictions' = ($Record.CustomVariable | Where-Object Name -EQ 'licensing_restrictions').Value
'agency_name' = ($Record.CustomVariable | Where-Object Name -EQ 'agency_name').Value
'application_info' = ($Record.CustomVariable | Where-Object Name -EQ 'application_info').Value
'support_hours' = ($Record.CustomVariable | Where-Object Name -EQ 'support_hours').Value
'dr_protection' = ($Record.CustomVariable | Where-Object Name -EQ 'dr_protection').Value
'startup_priority' = ($Record.CustomVariable | Where-Object Name -EQ 'startup_priority').Value
'disk_1_os' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_1_os').Value
'disk_2_swap_disk' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_2_swap_disk').Value
'disk_3' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_3').Value
'disk_4' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_4').Value
'disk_5' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_5').Value
'disk_6' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_6').Value
'disk_7' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_7').Value
'disk_8' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_8').Value
'disk_9' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_9').Value
'disk_10' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_10').Value
'disk_11' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_11').Value
'disk_12' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_12').Value
'disk_13' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_13').Value
'disk_14' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_14').Value
'disk_15' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_15').Value
'disk_16' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_16').Value
}
ForEach ($Property in $Record.PSObject.Properties) {
If ($obj.PSObject.Properties.Name -match $Property.Name) {
#Write-Verbose -Message ("Property " + $Property.Name + " already in obj")
}
Else {
$obj | Add-Member -MemberType $Property.MemberType -Name $Property.Name -Value $Property.Value -TypeName $Property.TypeNameOfValue -Verbose
}
}
ForEach ($Property in $Record.CustomVariable) {
If ($obj.PSObject.Properties.Name -match $Property.Name) {
#Write-Verbose -Message ("Property " + $Property.Name + " already in obj")
}
Else {
$obj | Add-Member -MemberType NoteProperty -Name $Property.Name -Value $Property.Value
}
}
$null = $RecordsToExport.Add($obj)
If ($RecordsToExport) { $RecordsToExport | Export-Csv "D:\OneDrive - State of North Dakota\RitmExportAppServer.csv" -Append -NoTypeInformation -Force }
}
}
}
+65
View File
@@ -0,0 +1,65 @@
$CurrentCsv = Import-Csv -Path "D:\OneDrive - State of North Dakota\RitmExportStorage.csv"
$NewestRecord = $CurrentCsv | Sort-Object -Descending number | select -First 1
[datetime]$StartDate = $NewestRecord.opened_at
#$StartDate = Get-date -Year 2020 -Month 1 -Day 1
[datetime]$EndDate = Get-Date #-Year 2023 -Month 3 -Day 30
$filter = @('cat_item', '-eq', '7c2457ae1bbfc9d06bc5cb751a4bcb69'),
'-and',
@('opened_at', '-gt', $StartDate ),
'-and',
@('opened_at', '-lt', $EndDate )
$RecordSearch = Get-ServiceNowRecord -Table 'Requested Item' -Filter $Filter -IncludeTotalCount | Sort-Object Number
$CurrentCsv = Import-Csv -Path "D:\OneDrive - State of North Dakota\RitmExportStorage.csv"
ForEach ($Record in $RecordSearch) {
Write-Warning -Message ("Begin record " + $Record.number)
If ( @($CurrentCsv.number | Where-Object { $_ -eq $Record.Number }).count -gt 0) {
Write-Warning -Message ("Number " + $Record.Number + " already in csv")
# do nothing
}
Else {
#Write-Warning -Message $record.number
$RecordDetail = Get-ServiceNowRecord -Table 'Requested Item' -ID $Record.Number -IncludeCustomVariable
ForEach ($Record in $RecordDetail) {
$RecordsToExport = [System.Collections.ArrayList]@()
$obj = [PSCustomObject][ordered]@{
'number' = $Record.number;
'sys_id' = $Record.sys_id;
'opened_at' = $Record.opened_at;
'requested_for' = $Record.requested_for.display_value;
'short_description' = $Record.short_description;
'description' = $Record.short_description;
'additional_comments' = ($Record.CustomVariable | Where-Object Name -EQ 'additional_comments').Value
'request_type' = ($Record.CustomVariable | Where-Object Name -EQ 'request_type').Value
'array_name' = ($Record.CustomVariable | Where-Object Name -EQ 'array_name').Value
'size' = ($Record.CustomVariable | Where-Object Name -EQ 'size').Value
'units' = ($Record.CustomVariable | Where-Object Name -EQ 'units').Value
'abr' = ($Record.CustomVariable | Where-Object Name -EQ 'abr').Value
'volume_name' = ($Record.CustomVariable | Where-Object Name -EQ 'volume_name').Value
}
ForEach ($Property in $Record.PSObject.Properties) {
If ($obj.PSObject.Properties.Name -match $Property.Name) {
#Write-Verbose -Message ("Property " + $Property.Name + " already in obj")
}
Else {
$obj | Add-Member -MemberType $Property.MemberType -Name $Property.Name -Value $Property.Value -TypeName $Property.TypeNameOfValue -Verbose
}
}
ForEach ($Property in $Record.CustomVariable) {
If ($obj.PSObject.Properties.Name -match $Property.Name) {
#Write-Verbose -Message ("Property " + $Property.Name + " already in obj")
}
Else {
$obj | Add-Member -MemberType NoteProperty -Name $Property.Name -Value $Property.Value
}
}
$null = $RecordsToExport.Add($obj)
If ($RecordsToExport) { $RecordsToExport | Export-Csv "D:\OneDrive - State of North Dakota\RitmExportStorage.csv" -Append -NoTypeInformation -Force }
}
}
}
+511
View File
@@ -0,0 +1,511 @@
# Configure variables below for connecting to the SQL database
################################################
$CSVFileName = "D:\OneDrive - State of North Dakota\ServiceNow\RitmDump-Application Server.csv"
$SQLInstance = "itdintsql22p1.nd.gov\intsql22p1"
$SQLDatabase = "ITD-Systems-Automation"
$SQLTable = "ServiceNow_RitmDump_ApplicationServerMK2"
$SQLTempDatabase = "ITD-Systems-Automation"
$SQLTempTable = "ServiceNow_RitmDump_ApplicationServerMK2_temp"
############################################################################################
# Nothing to change below this line, comments provided if you need/want to change anything
############################################################################################
##############################################
# Prompting for SQL credentials
##############################################
#$SQLCredentials = Get-Credential -Message "Enter your SQL username & password"
#$SQLUsername = $SQLCredentials.UserName
#$SQLPassword = $SQLCredentials.GetNetworkCredential().Password
$SQLCredentials = $PrvCred
##############################################
# Start of time taken benchmark
##############################################
$Start = Get-Date
##############################################
# Checking if SqlServer module is already installed, if not installing it
##############################################
$SQLModuleCheck = Get-Module -ListAvailable SqlServer
if ($SQLModuleCheck -eq $null) {
Write-Host "SqlServer Module Not Found - Installing"
# Not installed, trusting PS Gallery to remove prompt on install
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
# Installing module
Install-Module -Name SqlServer Scope CurrentUser -Confirm:$false -AllowClobber
}
##############################################
# Importing SqlServer module
##############################################
Import-Module SqlServer
##############################################
# Creating Temp SQL Table
##############################################
"Creating SQL Table $SQLTempTable for CSV Import"
$SQLCreateTempTable = "USE [ITD-Systems-Automation]
CREATE TABLE $SQLTempTable (
sys_id char(32) PRIMARY KEY,
number char(11),
opened_at datetime,
requested_for varchar(255),
sys_updated_on datetime,
short_description varchar(max),
active varchar(255),
activity_due varchar(255),
additional_assignee_list varchar(255),
additional_comments varchar(max),
add_change_disaster_recovery varchar(255),
agency_name varchar(255),
application_info varchar(255),
application_name varchar(255),
approval_history varchar(max),
assigned_to varchar(255),
assignment_group varchar(255),
backordered varchar(255),
billable varchar(255),
business_duration varchar(255),
business_service varchar(255),
calendar_duration varchar(255),
cat_item varchar(255),
cat_item_display_name varchar(255),
cidr_block varchar(255),
closed_at datetime,
closed_by varchar(255),
close_notes varchar(max),
cmdb_ci varchar(255),
comments varchar(max),
configuration_item varchar(255),
contact_type varchar(255),
contract varchar(255),
correlation_display varchar(255),
correlation_id varchar(255),
data_center varchar(255),
disaster_recovery_requirements varchar(255),
disk_10 varchar(255),
disk_11 varchar(255),
disk_12 varchar(255),
disk_13 varchar(255),
disk_14 varchar(255),
disk_15 varchar(255),
disk_16 varchar(255),
disk_1_os varchar(255),
disk_2_swap_disk varchar(255),
disk_3 varchar(255),
disk_4 varchar(255),
disk_5 varchar(255),
disk_6 varchar(255),
disk_7 varchar(255),
disk_8 varchar(255),
disk_9 varchar(255),
dr_protection varchar(255),
due_date varchar(255),
environment varchar(255),
escalation varchar(255),
estimated_delivery datetime,
expected_start varchar(255),
follow_up varchar(255),
group_list varchar(255),
host_name varchar(255),
impact varchar(255),
knowledge varchar(255),
licensing_restrictions varchar(255),
location varchar(255),
made_sla varchar(255),
memory_gb varchar(255),
opened_by varchar(255),
operating_system varchar(255),
order_guide varchar(255),
parent varchar(255),
pa_zone varchar(255),
price varchar(255),
priority varchar(255),
processors varchar(255),
quantity_sourced varchar(255),
reassignment_count varchar(255),
received varchar(255),
recurring_frequency varchar(255),
recurring_price varchar(255),
replaces_vm varchar(255),
request_type varchar(255),
required_date varchar(255),
require_hosting_quote varchar(255),
route_reason varchar(255),
sc_catalog varchar(255),
secure varchar(255),
server_name varchar(255),
server_type varchar(255),
service_offering varchar(255),
skills varchar(255),
sla_due varchar(255),
special_instructions varchar(255),
stage varchar(255),
startup_priority varchar(255),
state varchar(255),
support_hours varchar(255),
sys_class_name varchar(255),
sys_created_by varchar(255),
sys_created_on datetime,
sys_domain varchar(255),
sys_domain_path varchar(255),
sys_mod_count varchar(255),
sys_tags varchar(255),
sys_updated_by varchar(255),
target_os_version_linux varchar(255),
target_os_version_windows varchar(255),
target_platform varchar(255),
task_effective_number varchar(255),
team_lead varchar(255),
time_worked varchar(255),
universal_request varchar(255),
upon_approval varchar(255),
upon_reject varchar(255),
urgency varchar(255),
user_input varchar(255),
u_approval_flag varchar(255),
u_change_incident varchar(255),
u_effective_date varchar(255),
u_on_hold_reason varchar(255),
vlan_id varchar(255),
vm_work_needed varchar(255),
v_alt_contact varchar(255),
v_approval_charge_code varchar(255),
v_approval_department varchar(255),
v_approval_department_code varchar(255),
v_approval_division varchar(255),
v_approval_division_code varchar(255),
v_manager varchar(255),
v_requested_by varchar(255),
v_requested_for varchar(255),
v_user_email varchar(255),
v_user_in_servicenow varchar(255),
v_user_phone varchar(255),
watch_list varchar(255),
work_end varchar(255),
work_notes varchar(max),
work_start varchar(255)
);"
#Invoke-Sqlcmd -Query $SQLCreateTempTable -ServerInstance $SQLInstance -Username $SQLUsername -Password $SQLPassword
#Invoke-ITDSqlCmdJob -ServerInstance $SInstance -Database ITD-Systems-Automation -Credential $PrvCred -Query
Invoke-ITDSqlCmdJob -ServerInstance $SqlInstance -Database ITD-Systems-Automation -Credential $PrvCred -Query $SQLCreateTempTable
##############################################
# Importing CSV and processing data
##############################################
$CSVImport = Import-Csv -Path $CSVFileName
$CSVRowCount = $CSVImport.Count
##############################################
# ForEach CSV Line Inserting a row into the Temp SQL table
##############################################
"Inserting $CSVRowCount rows from CSV into SQL Table $SQLTempTable"
ForEach ($CSVLine in $CSVImport) {
Write-Warning -Message ("Start " + $CSVLine.number)
# Setting variables for the CSV line, ADD ALL 170 possible CSV columns here
$sys_id = $CSVLine.sys_id
$number = $CSVLine.number
$opened_at = $CSVLine.opened_at
$requested_for = $CSVLine.requested_for
$sys_updated_on = $CSVLine.sys_updated_on
$short_description = $CSVLine.short_description
$active = $CSVLine.active
$activity_due = $CSVLine.activity_due
$additional_assignee_list = $CSVLine.additional_assignee_list
$additional_comments = $CSVLine.additional_comments
$add_change_disaster_recovery = $CSVLine.add_change_disaster_recovery
$agency_name = $CSVLine.agency_name
$application_info = $CSVLine.application_info
$application_name = $CSVLine.application_name
$approval_history = $CSVLine.approval_history
$assigned_to = $CSVLine.assigned_to
$assignment_group = $CSVLine.assignment_group
$backordered = $CSVLine.backordered
$billable = $CSVLine.billable
$business_duration = $CSVLine.business_duration
$business_service = $CSVLine.business_service
$calendar_duration = $CSVLine.calendar_duration
$cat_item = $CSVLine.cat_item
$cat_item_display_name = $CSVLine.cat_item_display_name
$cidr_block = $CSVLine.cidr_block
$closed_at = $CSVLine.closed_at
$closed_by = $CSVLine.closed_by
$close_notes = $CSVLine.close_notes
$cmdb_ci = $CSVLine.cmdb_ci
$comments = $CSVLine.comments
$configuration_item = $CSVLine.configuration_item
$contact_type = $CSVLine.contact_type
$contract = $CSVLine.contract
$correlation_display = $CSVLine.correlation_display
$correlation_id = $CSVLine.correlation_id
$data_center = $CSVLine.data_center
$disaster_recovery_requirements = $CSVLine.disaster_recovery_requirements
$disk_10 = $CSVLine.disk_10
$disk_11 = $CSVLine.disk_11
$disk_12 = $CSVLine.disk_12
$disk_13 = $CSVLine.disk_13
$disk_14 = $CSVLine.disk_14
$disk_15 = $CSVLine.disk_15
$disk_16 = $CSVLine.disk_16
$disk_1_os = $CSVLine.disk_1_os
$disk_2_swap_disk = $CSVLine.disk_2_swap_disk
$disk_3 = $CSVLine.disk_3
$disk_4 = $CSVLine.disk_4
$disk_5 = $CSVLine.disk_5
$disk_6 = $CSVLine.disk_6
$disk_7 = $CSVLine.disk_7
$disk_8 = $CSVLine.disk_8
$disk_9 = $CSVLine.disk_9
$dr_protection = $CSVLine.dr_protection
$due_date = $CSVLine.due_date
$environment = $CSVLine.environment
$escalation = $CSVLine.escalation
$estimated_delivery = $CSVLine.estimated_delivery
$expected_start = $CSVLine.expected_start
$follow_up = $CSVLine.follow_up
$group_list = $CSVLine.group_list
$host_name = $CSVLine.host_name
$impact = $CSVLine.impact
$knowledge = $CSVLine.knowledge
$licensing_restrictions = $CSVLine.licensing_restrictions
$location = $CSVLine.location
$made_sla = $CSVLine.made_sla
$memory_gb = $CSVLine.memory_gb
$opened_by = $CSVLine.opened_by
$operating_system = $CSVLine.operating_system
$order_guide = $CSVLine.order_guide
$parent = $CSVLine.parent
$pa_zone = $CSVLine.pa_zone
$price = $CSVLine.price
$priority = $CSVLine.priority
$processors = $CSVLine.processors
$quantity_sourced = $CSVLine.quantity_sourced
$reassignment_count = $CSVLine.reassignment_count
$received = $CSVLine.received
$recurring_frequency = $CSVLine.recurring_frequency
$recurring_price = $CSVLine.recurring_price
$replaces_vm = $CSVLine.replaces_vm
$request_type = $CSVLine.request_type
$required_date = $CSVLine.required_date
$require_hosting_quote = $CSVLine.require_hosting_quote
$route_reason = $CSVLine.route_reason
$sc_catalog = $CSVLine.sc_catalog
$secure = $CSVLine.secure
$server_name = $CSVLine.server_name
$server_type = $CSVLine.server_type
$service_offering = $CSVLine.service_offering
$skills = $CSVLine.skills
$sla_due = $CSVLine.sla_due
$special_instructions = $CSVLine.special_instructions
$stage = $CSVLine.stage
$startup_priority = $CSVLine.startup_priority
$state = $CSVLine.state
$support_hours = $CSVLine.support_hours
$sys_class_name = $CSVLine.sys_class_name
$sys_created_by = $CSVLine.sys_created_by
$sys_created_on = $CSVLine.sys_created_on
$sys_domain = $CSVLine.sys_domain
$sys_domain_path = $CSVLine.sys_domain_path
$sys_mod_count = $CSVLine.sys_mod_count
$sys_tags = $CSVLine.sys_tags
$sys_updated_by = $CSVLine.sys_updated_by
$target_os_version_linux = $CSVLine.target_os_version_linux
$target_os_version_windows = $CSVLine.target_os_version_windows
$target_platform = $CSVLine.target_platform
$task_effective_number = $CSVLine.task_effective_number
$team_lead = $CSVLine.team_lead
$time_worked = $CSVLine.time_worked
$universal_request = $CSVLine.universal_request
$upon_approval = $CSVLine.upon_approval
$upon_reject = $CSVLine.upon_reject
$urgency = $CSVLine.urgency
$user_input = $CSVLine.user_input
$u_approval_flag = $CSVLine.u_approval_flag
$u_change_incident = $CSVLine.u_change_incident
$u_effective_date = $CSVLine.u_effective_date
$u_on_hold_reason = $CSVLine.u_on_hold_reason
$vlan_id = $CSVLine.vlan_id
$vm_work_needed = $CSVLine.vm_work_needed
$v_alt_contact = $CSVLine.v_alt_contact
$v_approval_charge_code = $CSVLine.v_approval_charge_code
$v_approval_department = $CSVLine.v_approval_department
$v_approval_department_code = $CSVLine.v_approval_department_code
$v_approval_division = $CSVLine.v_approval_division
$v_approval_division_code = $CSVLine.v_approval_division_code
$v_manager = $CSVLine.v_manager
$v_requested_by = $CSVLine.v_requested_by
$v_requested_for = $CSVLine.v_requested_for
$v_user_email = $CSVLine.v_user_email
$v_user_in_servicenow = $CSVLine.v_user_in_servicenow
$v_user_phone = $CSVLine.v_user_phone
$watch_list = $CSVLine.watch_list
$work_end = $CSVLine.work_end
$work_notes = $CSVLine.work_notes
$work_start = $CSVLine.work_start
$SQLInsert = "USE [$SQLTempDatabase]
INSERT INTO $SQLTempTable (sys_id, number, opened_at, requested_for, sys_updated_on, short_description, active, activity_due, additional_assignee_list, additional_comments, add_change_disaster_recovery, agency_name, application_info, application_name, approval_history, assigned_to, assignment_group, backordered, billable, business_duration, business_service, calendar_duration, cat_item, cat_item_display_name, cidr_block, closed_at, closed_by, close_notes, cmdb_ci, comments, configuration_item, contact_type, contract, correlation_display, correlation_id, data_center, disaster_recovery_requirements, disk_10, disk_11, disk_12, disk_13, disk_14, disk_15, disk_16, disk_1_os, disk_2_swap_disk, disk_3, disk_4, disk_5, disk_6, disk_7, disk_8, disk_9, dr_protection, due_date, environment, escalation, estimated_delivery, expected_start, follow_up, group_list, host_name, impact, knowledge, licensing_restrictions, location, made_sla, memory_gb, opened_by, operating_system, order_guide, parent, pa_zone, price, priority, processors, quantity_sourced, reassignment_count, received, recurring_frequency, recurring_price, replaces_vm, request_type, required_date, require_hosting_quote, route_reason, sc_catalog, secure, server_name, server_type, service_offering, skills, sla_due, special_instructions, stage, startup_priority, state, support_hours, sys_class_name, sys_created_by, sys_created_on, sys_domain, sys_domain_path, sys_mod_count, sys_tags, sys_updated_by, target_os_version_linux, target_os_version_windows, target_platform, task_effective_number, team_lead, time_worked, universal_request, upon_approval, upon_reject, urgency, user_input, u_approval_flag, u_change_incident, u_effective_date, u_on_hold_reason, vlan_id, vm_work_needed, v_alt_contact, v_approval_charge_code, v_approval_department, v_approval_department_code, v_approval_division, v_approval_division_code, v_manager, v_requested_by, v_requested_for, v_user_email, v_user_in_servicenow, v_user_phone, watch_list, work_end, work_notes, work_start)
VALUES('$sys_id', '$number', '$opened_at', '$requested_for', '$sys_updated_on', '$short_description', '$active', '$activity_due', '$additional_assignee_list', '$additional_comments', '$add_change_disaster_recovery', '$agency_name', '$application_info', '$application_name', '$approval_history', '$assigned_to', '$assignment_group', '$backordered', '$billable', '$business_duration', '$business_service', '$calendar_duration', '$cat_item', '$cat_item_display_name', '$cidr_block', '$closed_at', '$closed_by', '$close_notes', '$cmdb_ci', '$comments', '$configuration_item', '$contact_type', '$contract', '$correlation_display', '$correlation_id', '$data_center', '$disaster_recovery_requirements', '$disk_10', '$disk_11', '$disk_12', '$disk_13', '$disk_14', '$disk_15', '$disk_16', '$disk_1_os', '$disk_2_swap_disk', '$disk_3', '$disk_4', '$disk_5', '$disk_6', '$disk_7', '$disk_8', '$disk_9', '$dr_protection', '$due_date', '$environment', '$escalation', '$estimated_delivery', '$expected_start', '$follow_up', '$group_list', '$host_name', '$impact', '$knowledge', '$licensing_restrictions', '$location', '$made_sla', '$memory_gb', '$opened_by', '$operating_system', '$order_guide', '$parent', '$pa_zone', '$price', '$priority', '$processors', '$quantity_sourced', '$reassignment_count', '$received', '$recurring_frequency', '$recurring_price', '$replaces_vm', '$request_type', '$required_date', '$require_hosting_quote', '$route_reason', '$sc_catalog', '$secure', '$server_name', '$server_type', '$service_offering', '$skills', '$sla_due', '$special_instructions', '$stage', '$startup_priority', '$state', '$support_hours', '$sys_class_name', '$sys_created_by', '$sys_created_on', '$sys_domain', '$sys_domain_path', '$sys_mod_count', '$sys_tags', '$sys_updated_by', '$target_os_version_linux', '$target_os_version_windows', '$target_platform', '$task_effective_number', '$team_lead', '$time_worked', '$universal_request', '$upon_approval', '$upon_reject', '$urgency', '$user_input', '$u_approval_flag', '$u_change_incident', '$u_effective_date', '$u_on_hold_reason', '$vlan_id', '$vm_work_needed', '$v_alt_contact', '$v_approval_charge_code', '$v_approval_department', '$v_approval_department_code', '$v_approval_division', '$v_approval_division_code', '$v_manager', '$v_requested_by', '$v_requested_for', '$v_user_email', '$v_user_in_servicenow', '$v_user_phone', '$watch_list', '$work_end', '$work_notes', '$work_start');"
# Running the INSERT Query
#Invoke-Sqlcmd -Query $SQLInsert -ServerInstance $SQLInstance -Username $SQLUsername -Password $SQLPassword
Invoke-ITDSqlCmdJob -ServerInstance $SQLInstance -Database $SQLDatabase -Query $SQLInsert -Credential $PrvCred
# End of ForEach CSV line below
}
# End of ForEach CSV line above
##############################################
# Merging data from Temp Table to Target Table using SQL MERGE
##############################################
"Merging SQL Table Data from $SQLTempTable to $SQLTable"
# For more info, I.E to add DELETE as part of the MERGE, read: https://www.essentialsql.com/introduction-merge-statement/
$SQLMerge = "MERGE [$SQLDatabase].[dbo].[$SQLTable] Target
USING [$SQLTempDatabase].[dbo].[$SQLTempTable] Source
ON (Target.sys_id = Source.sys_id)
WHEN MATCHED
THEN UPDATE
SET Target.sys_id = Source.sys_id,
Target.number = Source.number,
Target.opened_at = Source.opened_at,
Target.requested_for = Source.requested_for,
Target.sys_updated_on = Source.sys_updated_on,
Target.short_description = Source.short_description,
Target.active = Source.active,
Target.activity_due = Source.activity_due,
Target.additional_assignee_list = Source.additional_assignee_list,
Target.additional_comments = Source.additional_comments,
Target.add_change_disaster_recovery = Source.add_change_disaster_recovery,
Target.agency_name = Source.agency_name,
Target.application_info = Source.application_info,
Target.application_name = Source.application_name,
Target.approval_history = Source.approval_history,
Target.assigned_to = Source.assigned_to,
Target.assignment_group = Source.assignment_group,
Target.backordered = Source.backordered,
Target.billable = Source.billable,
Target.business_duration = Source.business_duration,
Target.business_service = Source.business_service,
Target.calendar_duration = Source.calendar_duration,
Target.cat_item = Source.cat_item,
Target.cat_item_display_name = Source.cat_item_display_name,
Target.cidr_block = Source.cidr_block,
Target.closed_at = Source.closed_at,
Target.closed_by = Source.closed_by,
Target.close_notes = Source.close_notes,
Target.cmdb_ci = Source.cmdb_ci,
Target.comments = Source.comments,
Target.configuration_item = Source.configuration_item,
Target.contact_type = Source.contact_type,
Target.contract = Source.contract,
Target.correlation_display = Source.correlation_display,
Target.correlation_id = Source.correlation_id,
Target.data_center = Source.data_center,
Target.disaster_recovery_requirements = Source.disaster_recovery_requirements,
Target.disk_10 = Source.disk_10,
Target.disk_11 = Source.disk_11,
Target.disk_12 = Source.disk_12,
Target.disk_13 = Source.disk_13,
Target.disk_14 = Source.disk_14,
Target.disk_15 = Source.disk_15,
Target.disk_16 = Source.disk_16,
Target.disk_1_os = Source.disk_1_os,
Target.disk_2_swap_disk = Source.disk_2_swap_disk,
Target.disk_3 = Source.disk_3,
Target.disk_4 = Source.disk_4,
Target.disk_5 = Source.disk_5,
Target.disk_6 = Source.disk_6,
Target.disk_7 = Source.disk_7,
Target.disk_8 = Source.disk_8,
Target.disk_9 = Source.disk_9,
Target.dr_protection = Source.dr_protection,
Target.due_date = Source.due_date,
Target.environment = Source.environment,
Target.escalation = Source.escalation,
Target.estimated_delivery = Source.estimated_delivery,
Target.expected_start = Source.expected_start,
Target.follow_up = Source.follow_up,
Target.group_list = Source.group_list,
Target.host_name = Source.host_name,
Target.impact = Source.impact,
Target.knowledge = Source.knowledge,
Target.licensing_restrictions = Source.licensing_restrictions,
Target.location = Source.location,
Target.made_sla = Source.made_sla,
Target.memory_gb = Source.memory_gb,
Target.opened_by = Source.opened_by,
Target.operating_system = Source.operating_system,
Target.order_guide = Source.order_guide,
Target.parent = Source.parent,
Target.pa_zone = Source.pa_zone,
Target.price = Source.price,
Target.priority = Source.priority,
Target.processors = Source.processors,
Target.quantity_sourced = Source.quantity_sourced,
Target.reassignment_count = Source.reassignment_count,
Target.received = Source.received,
Target.recurring_frequency = Source.recurring_frequency,
Target.recurring_price = Source.recurring_price,
Target.replaces_vm = Source.replaces_vm,
Target.request_type = Source.request_type,
Target.required_date = Source.required_date,
Target.require_hosting_quote = Source.require_hosting_quote,
Target.route_reason = Source.route_reason,
Target.sc_catalog = Source.sc_catalog,
Target.secure = Source.secure,
Target.server_name = Source.server_name,
Target.server_type = Source.server_type,
Target.service_offering = Source.service_offering,
Target.skills = Source.skills,
Target.sla_due = Source.sla_due,
Target.special_instructions = Source.special_instructions,
Target.stage = Source.stage,
Target.startup_priority = Source.startup_priority,
Target.state = Source.state,
Target.support_hours = Source.support_hours,
Target.sys_class_name = Source.sys_class_name,
Target.sys_created_by = Source.sys_created_by,
Target.sys_created_on = Source.sys_created_on,
Target.sys_domain = Source.sys_domain,
Target.sys_domain_path = Source.sys_domain_path,
Target.sys_mod_count = Source.sys_mod_count,
Target.sys_tags = Source.sys_tags,
Target.sys_updated_by = Source.sys_updated_by,
Target.target_os_version_linux = Source.target_os_version_linux,
Target.target_os_version_windows = Source.target_os_version_windows,
Target.target_platform = Source.target_platform,
Target.task_effective_number = Source.task_effective_number,
Target.team_lead = Source.team_lead,
Target.time_worked = Source.time_worked,
Target.universal_request = Source.universal_request,
Target.upon_approval = Source.upon_approval,
Target.upon_reject = Source.upon_reject,
Target.urgency = Source.urgency,
Target.user_input = Source.user_input,
Target.u_approval_flag = Source.u_approval_flag,
Target.u_change_incident = Source.u_change_incident,
Target.u_effective_date = Source.u_effective_date,
Target.u_on_hold_reason = Source.u_on_hold_reason,
Target.vlan_id = Source.vlan_id,
Target.vm_work_needed = Source.vm_work_needed,
Target.v_alt_contact = Source.v_alt_contact,
Target.v_approval_charge_code = Source.v_approval_charge_code,
Target.v_approval_department = Source.v_approval_department,
Target.v_approval_department_code = Source.v_approval_department_code,
Target.v_approval_division = Source.v_approval_division,
Target.v_approval_division_code = Source.v_approval_division_code,
Target.v_manager = Source.v_manager,
Target.v_requested_by = Source.v_requested_by,
Target.v_requested_for = Source.v_requested_for,
Target.v_user_email = Source.v_user_email,
Target.v_user_in_servicenow = Source.v_user_in_servicenow,
Target.v_user_phone = Source.v_user_phone,
Target.watch_list = Source.watch_list,
Target.work_end = Source.work_end,
Target.work_notes = Source.work_notes,
Target.work_start = Source.work_start
WHEN NOT MATCHED BY TARGET
THEN INSERT (sys_id, number, opened_at, requested_for, sys_updated_on, short_description, active, activity_due, additional_assignee_list, additional_comments, add_change_disaster_recovery, agency_name, application_info, application_name, approval_history, assigned_to, assignment_group, backordered, billable, business_duration, business_service, calendar_duration, cat_item, cat_item_display_name, cidr_block, closed_at, closed_by, close_notes, cmdb_ci, comments, configuration_item, contact_type, contract, correlation_display, correlation_id, data_center, disaster_recovery_requirements, disk_10, disk_11, disk_12, disk_13, disk_14, disk_15, disk_16, disk_1_os, disk_2_swap_disk, disk_3, disk_4, disk_5, disk_6, disk_7, disk_8, disk_9, dr_protection, due_date, environment, escalation, estimated_delivery, expected_start, follow_up, group_list, host_name, impact, knowledge, licensing_restrictions, location, made_sla, memory_gb, opened_by, operating_system, order_guide, parent, pa_zone, price, priority, processors, quantity_sourced, reassignment_count, received, recurring_frequency, recurring_price, replaces_vm, request_type, required_date, require_hosting_quote, route_reason, sc_catalog, secure, server_name, server_type, service_offering, skills, sla_due, special_instructions, stage, startup_priority, state, support_hours, sys_class_name, sys_created_by, sys_created_on, sys_domain, sys_domain_path, sys_mod_count, sys_tags, sys_updated_by, target_os_version_linux, target_os_version_windows, target_platform, task_effective_number, team_lead, time_worked, universal_request, upon_approval, upon_reject, urgency, user_input, u_approval_flag, u_change_incident, u_effective_date, u_on_hold_reason, vlan_id, vm_work_needed, v_alt_contact, v_approval_charge_code, v_approval_department, v_approval_department_code, v_approval_division, v_approval_division_code, v_manager, v_requested_by, v_requested_for, v_user_email, v_user_in_servicenow, v_user_phone, watch_list, work_end, work_notes, work_start)
VALUES (Source.sys_id, Source.number, Source.opened_at, Source.requested_for, Source.sys_updated_on, Source.short_description, Source.active, Source.activity_due, Source.additional_assignee_list, Source.additional_comments, Source.add_change_disaster_recovery, Source.agency_name, Source.application_info, Source.application_name, Source.approval_history, Source.assigned_to, Source.assignment_group, Source.backordered, Source.billable, Source.business_duration, Source.business_service, Source.calendar_duration, Source.cat_item, Source.cat_item_display_name, Source.cidr_block, Source.closed_at, Source.closed_by, Source.close_notes, Source.cmdb_ci, Source.comments, Source.configuration_item, Source.contact_type, Source.contract, Source.correlation_display, Source.correlation_id, Source.data_center, Source.disaster_recovery_requirements, Source.disk_10, Source.disk_11, Source.disk_12, Source.disk_13, Source.disk_14, Source.disk_15, Source.disk_16, Source.disk_1_os, Source.disk_2_swap_disk, Source.disk_3, Source.disk_4, Source.disk_5, Source.disk_6, Source.disk_7, Source.disk_8, Source.disk_9, Source.dr_protection, Source.due_date, Source.environment, Source.escalation, Source.estimated_delivery, Source.expected_start, Source.follow_up, Source.group_list, Source.host_name, Source.impact, Source.knowledge, Source.licensing_restrictions, Source.location, Source.made_sla, Source.memory_gb, Source.opened_by, Source.operating_system, Source.order_guide, Source.parent, Source.pa_zone, Source.price, Source.priority, Source.processors, Source.quantity_sourced, Source.reassignment_count, Source.received, Source.recurring_frequency, Source.recurring_price, Source.replaces_vm, Source.request_type, Source.required_date, Source.require_hosting_quote, Source.route_reason, Source.sc_catalog, Source.secure, Source.server_name, Source.server_type, Source.service_offering, Source.skills, Source.sla_due, Source.special_instructions, Source.stage, Source.startup_priority, Source.state, Source.support_hours, Source.sys_class_name, Source.sys_created_by, Source.sys_created_on, Source.sys_domain, Source.sys_domain_path, Source.sys_mod_count, Source.sys_tags, Source.sys_updated_by, Source.target_os_version_linux, Source.target_os_version_windows, Source.target_platform, Source.task_effective_number, Source.team_lead, Source.time_worked, Source.universal_request, Source.upon_approval, Source.upon_reject, Source.urgency, Source.user_input, Source.u_approval_flag, Source.u_change_incident, Source.u_effective_date, Source.u_on_hold_reason, Source.vlan_id, Source.vm_work_needed, Source.v_alt_contact, Source.v_approval_charge_code, Source.v_approval_department, Source.v_approval_department_code, Source.v_approval_division, Source.v_approval_division_code, Source.v_manager, Source.v_requested_by, Source.v_requested_for, Source.v_user_email, Source.v_user_in_servicenow, Source.v_user_phone, Source.watch_list, Source.work_end, Source.work_notes, Source.work_start);"
#Invoke-Sqlcmd -Query $SQLMerge -ServerInstance $SQLInstance -Username $SQLUsername -Password $SQLPassword
Invoke-ITDSqlCmdJob -ServerInstance $SqlInstance -Database $SQLDatabase -Query $SQLMerge -Credential $PrvCred
##############################################
# Dropping Temp Table using SQL DROP
##############################################
"Dropping SQL Table $SQLTempTable as no longer needed"
$SQLDrop = "USE [$SQLTempDatabase]
DROP TABLE $SQLTempTable;"
#Invoke-Sqlcmd -Query $SQLDrop -ServerInstance $SQLInstance -Username $SQLUsername -Password $SQLPassword
Invoke-ITDSqlCmdJob -ServerInstance $SqlInstance -Database $SQLDatabase -Query $SQLDrop -Credential $PrvCred
##############################################
+151
View File
@@ -0,0 +1,151 @@
# modified last hour block
#[datetime]$StartDate = (Get-Date -Minute 0 -Second 0).AddHours(-1)
#[datetime]$EndDate = (Get-Date -Minute 59 -Second 59).AddHours(-1)
# modified yesterday
#[datetime]$StartDate = (Get-Date -Hour 0 -Minute 0 -Second 0).AddDays(-1)
#[datetime]$EndDate = (Get-Date -hour 23 -Minute 59 -Second 59).AddDays(-1)
# modified 2023
[datetime]$StartDate = (Get-Date -Year 2023 -Month 4 -Day 1 -Hour 0 -Minute 0 -Second 0).AddDays(-1)
[datetime]$EndDate = (Get-Date -Year 2023 -Month 5 -Day 31 -Hour 23 -Minute 59 -Second 59).AddDays(-1)
# edit filter as needed
$Filter = @('cat_item', '-eq', '89efc7041bb41dd04d8943b1b24bcb63'),
'-and',
@('sys_updated_on', '-gt', $StartDate ),
'-and',
@('sys_updated_on', '-lt', $EndDate )
#>
$RecordSearch = Get-ServiceNowRecord -Table 'Requested Item' -Filter $Filter -IncludeTotalCount | select *, @{n = 'cat_item_display_name'; e = { $_.cat_item.display_value } }
# TO-DO: loop each cat_item_display_name, and export to dedicated csv
$CatItemDisplayNames = ($RecordSearch | Select-Object -Unique cat_item_display_name).cat_item_display_name
ForEach ($CatItemDisplayName in $CatItemDisplayNames) {
Clear-Variable -Name RecordsToImport -ErrorAction SilentlyContinue
$RecordsToImport = $RecordSearch | Where-Object cat_item_display_name -EQ $CatItemDisplayName
$CsvPath = "D:\OneDrive - State of North Dakota\ServiceNow\RitmDump-$CatItemDisplayName.csv"
Write-Warning -Message ($CatItemDisplayName + " records to import = " + $RecordsToImport.count)
$RecordsToExport = [System.Collections.ArrayList]@()
ForEach ($Record in $RecordsToImport) {
Write-Warning -Message ("Begin record " + $Record.number)
$RecordDetail = Get-ServiceNowRecord -Table 'Requested Item' -ID $Record.Number -IncludeCustomVariable
$obj = [PSCustomObject][ordered]@{
'number' = $Record.number;
'sys_id' = $Record.sys_id;
'opened_at' = $Record.opened_at;
'requested_for' = $Record.requested_for.display_value;
'sys_updated_on' = $Record.sys_updated_on
'short_description' = $Record.short_description;
}
ForEach ($Property in $Record.PSObject.Properties) {
If ($obj.PSObject.Properties.Name -match $Property.Name) {
#Write-Verbose -Message ("Property " + $Property.Name + " already in obj")
}
Else {
# add missing default RITM property to new obj
$obj | Add-Member -MemberType $Property.MemberType -Name $Property.Name -Value $Property.Value -TypeName $Property.TypeNameOfValue -Verbose
}
}
ForEach ($Property in ($RecordDetail.CustomVariable | Sort-Object Name)) {
If ($obj.PSObject.Properties.Name -match $Property.Name) {
#Write-Verbose -Message ("Property " + $Property.Name + " already in obj")
}
Else {
# add missing custom variables to new obj
$obj | Add-Member -MemberType NoteProperty -Name $Property.Name -Value $Property.Value
}
}#>
$null = $RecordsToExport.Add($obj)
}
If ($RecordsToExport) { $RecordsToExport | Export-Csv $CsvPath -Append -NoTypeInformation -Force }
}
<#
$CurrentCsv = Import-Csv -Path $CsvPath
ForEach ($Record in $RecordSearch) {
Write-Warning -Message ("Begin record " + $Record.number)
If ( @($CurrentCsv.number | Where-Object { $_ -eq $Record.Number }).count -gt 0) {
Write-Warning -Message ("Number " + $Record.Number + " already in csv")
# do nothing
}
Else {
#Write-Warning -Message $record.number
$RecordDetail = Get-ServiceNowRecord -Table 'Requested Item' -ID $Record.Number -IncludeCustomVariable
ForEach ($Record in $RecordDetail) {
$RecordsToExport = [System.Collections.ArrayList]@()
$obj = [PSCustomObject][ordered]@{
# get specific custom fields first, so the columns are on the left of csv
'number' = $Record.number;
'sys_id' = $Record.sys_id;
'opened_at' = $Record.opened_at;
'requested_for' = $Record.requested_for.display_value;
'short_description' = $Record.short_description;
'request_type' = ($Record.CustomVariable | Where-Object Name -EQ 'request_type').Value
'application_name' = ($Record.CustomVariable | Where-Object Name -EQ 'application_name').Value
'environment' = ($Record.CustomVariable | Where-Object Name -EQ 'environment').Value
'additional_comments' = ($Record.CustomVariable | Where-Object Name -EQ 'additional_comments').Value
'vm_work_needed' = ($Record.CustomVariable | Where-Object Name -EQ 'vm_work_needed').Value
'server_name' = ($Record.CustomVariable | Where-Object Name -EQ 'server_name').Value
'host_name' = ($Record.CustomVariable | Where-Object Name -EQ 'host_name').Value
'server_type' = ($Record.CustomVariable | Where-Object Name -EQ 'server_type').Value
'operating_system' = ($Record.CustomVariable | Where-Object Name -EQ 'operating_system').Value
'target_platform' = ($Record.CustomVariable | Where-Object Name -EQ 'target_platform').Value
'processors' = ($Record.CustomVariable | Where-Object Name -EQ 'processors').Value
'memory_gb' = ($Record.CustomVariable | Where-Object Name -EQ 'memory_gb').Value
'cidr_block' = ($Record.CustomVariable | Where-Object Name -EQ 'cidr_block').Value
'data_center' = ($Record.CustomVariable | Where-Object Name -EQ 'data_center').Value
'licensing_restrictions' = ($Record.CustomVariable | Where-Object Name -EQ 'licensing_restrictions').Value
'agency_name' = ($Record.CustomVariable | Where-Object Name -EQ 'agency_name').Value
'application_info' = ($Record.CustomVariable | Where-Object Name -EQ 'application_info').Value
'support_hours' = ($Record.CustomVariable | Where-Object Name -EQ 'support_hours').Value
'dr_protection' = ($Record.CustomVariable | Where-Object Name -EQ 'dr_protection').Value
'startup_priority' = ($Record.CustomVariable | Where-Object Name -EQ 'startup_priority').Value
'disk_1_os' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_1_os').Value
'disk_2_swap_disk' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_2_swap_disk').Value
'disk_3' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_3').Value
'disk_4' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_4').Value
'disk_5' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_5').Value
'disk_6' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_6').Value
'disk_7' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_7').Value
'disk_8' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_8').Value
'disk_9' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_9').Value
'disk_10' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_10').Value
'disk_11' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_11').Value
'disk_12' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_12').Value
'disk_13' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_13').Value
'disk_14' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_14').Value
'disk_15' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_15').Value
'disk_16' = ($Record.CustomVariable | Where-Object Name -EQ 'disk_16').Value
}
ForEach ($Property in $Record.PSObject.Properties) {
If ($obj.PSObject.Properties.Name -match $Property.Name) {
#Write-Verbose -Message ("Property " + $Property.Name + " already in obj")
}
Else {
# add missing default RITM property to new obj
$obj | Add-Member -MemberType $Property.MemberType -Name $Property.Name -Value $Property.Value -TypeName $Property.TypeNameOfValue -Verbose
}
}
ForEach ($Property in $Record.CustomVariable) {
If ($obj.PSObject.Properties.Name -match $Property.Name) {
#Write-Verbose -Message ("Property " + $Property.Name + " already in obj")
}
Else {
# add missing custom variables to new obj
$obj | Add-Member -MemberType NoteProperty -Name $Property.Name -Value $Property.Value
}
}
$null = $RecordsToExport.Add($obj)
If ($RecordsToExport) { $RecordsToExport | Export-Csv $CsvPath -Append -NoTypeInformation -Force }
}
}
}
#>
+21
View File
@@ -0,0 +1,21 @@
#Add to Local Security Policy
function Add-ServiceLogonRight([string] $Username) {
Write-Host "Enable ServiceLogonRight for $Username"
$tmp = New-TemporaryFile
secedit /export /cfg "$tmp.inf" | Out-Null
(Get-Content -Encoding ascii "$tmp.inf") -replace '^SeServiceLogonRight .+', "`$0,$Username" | sc -Encoding ascii "$tmp.inf"
secedit /import /cfg "$tmp.inf" /db "$tmp.sdb" | Out-Null
secedit /configure /db "$tmp.sdb" /cfg "$tmp.inf" | Out-Null
Remove-Item $tmp* -ea 0
}
Add-ServiceLogonRight -Username svccohesitysql
# Set Service to Run as Service Account
Stop-Service -Name CohesityAgent
sc.exe config "CohesityAgent" obj="NDGOV\svccohesitysql" password="radiant-yx8aHMrGtc"
Start-Service -Name CohesityAgent
# Add to Local Administrators group
Add-LocalGroupMember -Group Administrators -Member "ndgov\svccohesitysql"
+18
View File
@@ -0,0 +1,18 @@
#remediate
Invoke-Command -Scriptblock {
cscript C:\Windows\System32\slmgr.vbs -upk
cscript C:\Windows\System32\slmgr.vbs -ipk MMFTT-7FBRY-W9QYW-37FMB-TRPJK
cscript C:\Windows\System32\slmgr.vbs -ato 553673ed-6ddf-419c-a153-b760283472fd
}
# Discovery
$Compliant = $false
$ActivationString = Invoke-Command -Scriptblock { cscript C:\Windows\System32\slmgr.vbs -xpr } -Session $x
If ($ActivationString -like "Windows(R) 7, Server-ESU-Year1 edition*" -and $ActivationString -like "*The machine is permanently activated.*") {
$Compliant = $true
}
else {
$Compliant = $false
}
$Compliant
+20
View File
@@ -0,0 +1,20 @@
<#
Requirements:
Needs SpotDL python project installed
#>
New-Item -Path "D:\" -Name ("spotdl_" + (Get-Date -UFormat "%y%m%d")) -ItemType Directory
$RootUrl = "https://xmplaylist.com/api/station/thehighway/most-heard"
$DaysToReview = @(7, 30, 60)
ForEach ($subdays in $DaysToReview) {
#write-warning ($url + "?subdays=" + $subdays)
$result += Invoke-RestMethod -Uri ($RootUrl + "?subDays=" + $subdays) -Method Get -ContentType "application/json"
}
$UniqueTracks = ($Result | Select -Unique id).Id
ForEach ($Id in $UniqueTracks) {
$Url = (($Result | Where-Object Id -eq $Id | Select -First 1).links | where-object site -eq spotify | select -first 1).url
Invoke-Expression -Command ("spotdl " + $Url)
}
+58
View File
@@ -0,0 +1,58 @@
$transcript = Get-Content D:\Downloads\transcript.txt
$RawResult = [System.Collections.ArrayList]@()
$x = 0
While ($x -lt (@($transcript).count)) {
$obj = [pscustomobject]@{
timestamp = $transcript[$x + 0]
speaker = $transcript[$x + 1]
words = $transcript[$x + 2]
}
$null = $RawResult.Add($obj)
$x = $x + 3
}
$WordsResult = [System.Collections.ArrayList]@()
ForEach ($dialog in $RawResult) {
ForEach ($word in $dialog.words.split(' ')) {
$word = [regex]::Replace($word, "[^a-zA-Z0-9\s]", "")
$obj = [pscustomobject]@{
timestamp = $dialog.timestamp
speaker = $dialog.speaker
word = $word
}
$null = $WordsResult.Add($obj)
}
}
# Top 300 Words
$WordsResult | Group-Object Word | Sort-Object -Descending Count | select -First 300
# Top words by speaker
$WordsBySpeakerResult = [System.Collections.ArrayList]@()
$DialogBySpeaker = $WordsResult | Group-Object speaker
ForEach ($speaker in $DialogBySpeaker) {
$Top10SpeakerWords = $speaker.Group | Group-Object Word | Sort-Object -Descending Count | select -First 10
$obj = [pscustomobject]@{
speaker = $speaker.name
word1 = $Top10SpeakerWords[0].Name
word2 = $Top10SpeakerWords[1].Name
word3 = $Top10SpeakerWords[2].Name
word4 = $Top10SpeakerWords[3].Name
word5 = $Top10SpeakerWords[4].Name
word6 = $Top10SpeakerWords[5].Name
word7 = $Top10SpeakerWords[6].Name
word8 = $Top10SpeakerWords[7].Name
word9 = $Top10SpeakerWords[8].Name
word10 = $Top10SpeakerWords[9].Name
}
$null = $WordsBySpeakerResult.Add($obj)
}
$TopNouns = (Import-Csv "D:\Downloads\english-word-list-nouns.csv" -Delimiter ';').word
$FilteredWordsResult = $WordsResult
+14
View File
@@ -0,0 +1,14 @@
$Func = {
param($C)
Import-SWDiscovery -ComputerName $C -Integration ServiceNow
}
Invoke-Command -ComputerName itdslrwndstst2.nd.gov -ScriptBlock $Func -ArgumentList $FQDN -Credential $SwCred
$Func = {
param($c)
Import-SWDiscovery -ComputerName $c -Integration ServiceNow
}
Invoke-Command -ComputerName itdslrwnds.nd.gov -ScriptBlock $Func -ArgumentList itdcndstfc19.nd.gov -Credential $IaaSAuto #Cred
+74
View File
@@ -0,0 +1,74 @@
# shutdown VDI via GUI
# Get All VMs 5 minutes
$AllVMs = Get-Datacenter -Name Primary* | Get-Cluster | Where-Object Name -ne MGMT1 | Get-VM
$AllVMTags = $AllVMs | Get-TagAssignment -Category DTAP, StartupPriority # 3.5 minutes
# while that runs, vmotion des-cad rabbitmq ??? contact Shawn F for Solarwinds
<# retag VMware VMs to Priority 0
get-vm -name itdvm* | Get-TagAssignment -Category StartupPriority | Remove-TagAssignment -Confirm:$false
$Tag = Get-Tag -Category StartupPriority -Name 0 -Server itdvmvc1.nd.gov
get-vm -name itdvm* | Get-TagAssignment -Category StartupPriority | Remove-TagAssignment -Confirm:$false
Get-VM -name itdvm* | ForEach-Object{
$ViServer=$_.Uid.split('@')[1].split(':')[0]
$Tag = Get-Tag -Category StartupPriority -Name 0 -Server $ViServer
$_ | New-TagAssignment -Tag $Tag
}
#>
$AllVMsWithTags = [System.Collections.ArrayList]@()
ForEach ($VM in $AllVMs) {
$obj = [PSCustomObject]@{
'VMName' = $VM.Name;
'DTAP' = ($AllVMTags | Where-Object { $_.Entity.Name -eq $VM.Name -and $_.Tag.Category.Name -eq 'DTAP' }).Tag.Name
'StartupPriority' = ($AllVMTags | Where-Object { $_.Entity.Name -eq $VM.Name -and $_.Tag.Category.Name -eq 'StartupPriority' }).Tag.Name
}
#Write-Output $obj
$null = $AllVMsWithTags.Add($obj)
}
#Populate variables
$AllTest5 = $AllVMsWithTags | Where-Object {$_.StartupPriority -eq 5 -and $_.DTAP -eq 'Test'}
$AllTest4 = $AllVMsWithTags | Where-Object {$_.StartupPriority -eq 4 -and $_.DTAP -eq 'Test'}
$AllTest3 = $AllVMsWithTags | Where-Object {$_.StartupPriority -eq 3 -and $_.DTAP -eq 'Test'}
$AllTest2 = $AllVMsWithTags | Where-Object {$_.StartupPriority -eq 2 -and $_.DTAP -eq 'Test'}
$AllTest1 = $AllVMsWithTags | Where-Object {$_.StartupPriority -eq 1 -and $_.DTAP -eq 'Test'}
<#
$AllProd5 = $AllVMsWithTags | Where-Object {$_.StartupPriority -eq 5 -and $_.DTAP -eq 'Production'}
$AllProd4 = $AllVMsWithTags | Where-Object {$_.StartupPriority -eq 4 -and $_.DTAP -eq 'Production'}
$AllProd3 = $AllVMsWithTags | Where-Object {$_.StartupPriority -eq 3 -and $_.DTAP -eq 'Production'}
$AllProd2 = $AllVMsWithTags | Where-Object {$_.StartupPriority -eq 2 -and $_.DTAP -eq 'Production'}
$AllProd1 = $AllVMsWithTags | Where-Object {$_.StartupPriority -eq 1 -and $_.DTAP -eq 'Production'}
#>
# shutdown VMs by variable group
ForEach($VM in $AllTest5){
Get-VM -Name $VM.VMName -Server itdvmvc1.nd.gov #|Stop-VMGuest
}
# monitor the shutdown
Get-Datacenter -Name Primary* | Get-VM -Name $AllTest5.VMName
# disable all host alarms and put all hosts into maintenance
$AllVMHosts = Get-Datacenter -Name Primary* | Get-Cluster | Where-Object Name -ne MGMT1 | Get-VMHost
foreach ($VMHostName in $AllVMHosts) {
Write-Warning -Message ("Start $VMHostName")
$GetVMHost = Get-VMHost $VMHostName
$VIServer = $GetVMHost.Uid.Split('@')[1].Split(':')[0]
$alarmMgr = Get-View AlarmManager -Server $VIServer
$alarmEnabled = $GetVMHost.ExtensionData.AlarmActionsEnabled
if ($alarmEnabled -eq $true) {
$alarmMgr.EnableAlarmActions($GetVMHost.ExtensionData.MoRef, $false)
}
}
# maintenance manually in GUI *******************************
# shutdown manually in GUI *******************************
+960
View File
@@ -0,0 +1,960 @@
# looper
<#
#>
$FQDNs = @"
itdpszeeland1.nd.gov
"@
$FQDNs = ConvertTo-Array -MultiLineString $FQDNs
ForEach ($FQDN in $FQDNs) {
Write-Warning "[$FQDN]:Start"
$SPCred = $StdCred
$ADCred = $PrvCred
$PSCred = $PrvCred
$VMCred = $PrvCred
$CcmCred = $PrvCred
#>
<# Get Credentials
$SPCred = Get-AutomationPSCredential -Name 'SharePoint IaaS ReadWrite'
$ADCred = Get-AutomationPSCredential -Name 'ITD IaaS Automation'
$PSCred = Get-AutomationPSCredential -Name 'ITD IaaS Automation'
$IBCred = New-Object System.Management.Automation.PSCredential ($PSCred.UserName.split('\')[1], $ADCred.Password)
$VMCred = Get-AutomationPSCredential -Name 'VMware Auto'
$CcmCred = Get-AutomationPSCredential -Name 'ITD IaaS Automation'#>
#>
Clear-DnsClientCache
$SharePointList = Get-ITDVMwareSharePointVMGuestList -Credential $SPCred
Write-Warning ("SPList count: " + $SharePointList.count)
$SPItem = $SharePointList | Where-Object Title -EQ $FQDN
If ($null -eq $SPItem.Cluster) {
Write-Error "VMware Cluster not specified in SharePoint"
Stop
}
Write-Warning $SPItem
$HostName = $FQDN.split('.')[0]
# Infoblox
[Net.IpAddress]$NetworkId = $SPItem.CIDR.split('/')[0]
[Net.IPAddress]$IpAddress = (Resolve-DnsName -Name $FQDN -ErrorAction SilentlyContinue).IPAddress
$SubnetMaskInt = $SPItem.Cidr.split('/')[1]
$Int64 = ([convert]::ToInt64(('1' * $SubnetMaskInt + '0' * (32 - $SubnetMaskInt)), 2))
[Net.IPAddress]$SubnetMask = '{0}.{1}.{2}.{3}' -f ([math]::Truncate($Int64 / 16777216)).ToString(),
([math]::Truncate(($Int64 % 16777216) / 65536)).ToString(),
([math]::Truncate(($Int64 % 65536) / 256)).ToString(),
([math]::Truncate($Int64 % 256)).ToString()
$IPSplit = $SPItem.Cidr.Split('.')
[Net.IPAddress]$DefaultGateway = ($IPSplit[0] + '.' + $IPSplit[1] + '.' + $IPSplit[2] + '.' + (($SPItem.Cidr.split('/')[0].split('.')[-1] -as [int]) + 1) )
<#
If (($IpAddress.Address -band $SubnetMask.Address) -eq ($NetworkId.Address -band $SubnetMask.Address)) {
Write-Verbose "IP Address and CIDR Block match"
}
Else {
Write-Error "DNS record already exists, and does not match CIDR Block" -ErrorAction Stop
}
#>
If ($IpAddress) {
If (($IpAddress.Address -band $SubnetMask.Address) -eq ($NetworkId.Address -band $SubnetMask.Address)) {
Write-Warning "DNS record already exists, CIDR Block match"
}
else {
Write-Error "DNS record already exists, and does not match CIDR Block"
Break
}
}
Else {
New-ITDIbDNSRecordNextAvailableIP -Hostname $SPItem.Title -CIDR $SPItem.CIDR -Credential $RadiusCred
[Net.IPAddress]$IpAddress = (Resolve-DnsName -Name $FQDN -ErrorAction SilentlyContinue).IPAddress
}
#>
If ((Test-NetConnection -ComputerName $IpAddress.IPAddressToString).PingSucceeded) {
Write-Error "IP Address already in use." -ErrorAction Stop
}
# Passwordstate BB before baseline, AB after baseline
If ($FQDN -like "itdcnd*") {
$PasswordStateList = "Peoplesoft Share PW"
}
Else {
$PasswordStateList = "CSRC"
}
$LocalCredential = New-ITDPassword -Title $FQDN -UserName itdadmin -Description 'Local Administrator' -PasswordList $PasswordStateList -Credential $PSCred
$GuestCredentialBB = New-Object System.Management.Automation.PSCredential ('Administrator', ($LocalCredential.Password | ConvertTo-SecureString -AsPlainText -Force))
$GuestCredentialAB = New-Object System.Management.Automation.PSCredential ($LocalCredential.UserName, ($LocalCredential.Password | ConvertTo-SecureString -AsPlainText -Force))
$GuestCredential = $GuestCredentialBB
# VMware
Connect-ITDvCenter -Credential $VMCred
If (Get-VM -Name $FQDN -ErrorAction SilentlyContinue) {
Write-Error "Virtual machine with the name $FQDN already exists." -ErrorAction Stop
Stop
Stop
}
switch ($SPItem.Cluster) {
"WINDOWS1" {
$ViServer = 'itdvmvc1.nd.gov'
$ComputeCluster = Get-Cluster WINDOWS1
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-PDC-Data-Server"
$DiskStorageFormat = 'Thin'
If ($SPItem.LicensingRestrictions -like "*SQL*") {
$DatastoreCluster = Get-DatastoreCluster -Name "WINDOWS1_FS92_SQL"
}
Else {
$DatastoreCluster = Get-DatastoreCluster -Name "WINDOWS1_FS92_Gen"
}
}
"WINDOWS2" {
$ViServer = 'itdvmvc2.nd.gov'
$ComputeCluster = Get-Cluster WINDOWS2
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-SDC-Data-Server"
$DiskStorageFormat = 'Thin'
If ($SPItem.LicensingRestrictions -like "*SQL*") {
$DatastoreCluster = Get-DatastoreCluster -Name "WINDOWS2_FS92_SQL"
}
Else {
$DatastoreCluster = Get-DatastoreCluster -Name "WINDOWS2_FS92_Gen"
}
}
"SQL1" {
$ViServer = 'itdvmvc1.nd.gov'
$ComputeCluster = Get-Cluster SQL1
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-PDC-Data-Server"
$DiskStorageFormat = 'EagerZeroedThick'
$DatastoreCluster = Get-DatastoreCluster -Name "SQL1_FS92_Gen"
}
"SQL2" {
$ViServer = 'itdvmvc2.nd.gov'
$ComputeCluster = Get-Cluster SQL2
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-SDC-Data-Server"
$DiskStorageFormat = 'EagerZeroedThick'
$DatastoreCluster = Get-DatastoreCluster -Name "SQL2_FS92_Gen"
}
"WAS1" {
$ViServer = 'itdvmvc1.nd.gov'
$ComputeCluster = Get-Cluster WAS1
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-PDC-Data-Server"
$DiskStorageFormat = 'Thin'
$DatastoreCluster = Get-DatastoreCluster -Name "WAS1_FS92_Gen"
}
"WAS2" {
$ViServer = 'itdvmvc2.nd.gov'
$ComputeCluster = Get-Cluster WAS2
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-SDC-Data-Server"
$DiskStorageFormat = 'Thin'
$DatastoreCluster = Get-DatastoreCluster -Name "WAS2_FS92_Gen"
}
"PS1" {
$ViServer = 'itdvmvc1.nd.gov'
$ComputeCluster = Get-Cluster PS1
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-PDC-Data-Server"
$DiskStorageFormat = 'Thin'
$DatastoreCluster = Get-DatastoreCluster -Name "PS1_FS92_Gen"
}
"PS2" {
$ViServer = 'itdvmvc2.nd.gov'
$ComputeCluster = Get-Cluster PS2
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-SDC-Data-Server"
$DiskStorageFormat = 'Thin'
$DatastoreCluster = Get-DatastoreCluster -Name "PS2_FS92_Gen"
}
"TEL1" {
$ViServer = 'itdvmvc1.nd.gov'
$ComputeCluster = Get-Cluster TEL1
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-PDC-TEL1-Data"
$DiskStorageFormat = 'Thin'
$DatastoreCluster = Get-DatastoreCluster -Name "TEL1_FS92_Gen"
}
"TEL2" {
$ViServer = 'itdvmvc2.nd.gov'
$ComputeCluster = Get-Cluster TEL2
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-PDC-TEL2-Data"
$DiskStorageFormat = 'Thin'
$DatastoreCluster = Get-DatastoreCluster -Name "TEL2_FS92_Gen"
}
Default {
Write-Error "Cluster not found" -ErrorAction Stop
}
<#
"DCN1" {
$ViServer = 'itdvmvc1.nd.gov'
$VirtualSwitch = Get-VDSwitch -Name "dvSwitch-DCN-vMotion-Data"
$DiskStorageFormat = 'Thin'
}
#>
}
# verify disk will fit
$DiskTotal = $SPItem.Disk1 + $SPItem.Disk2 + $SPItem.Disk3
If ($DatastoreCluster) {
}
Else {
$DatastoreCluster = Get-DatastoreCluster | Where-Object Name -Like ("*" + $SPItem.Cluster + "*")
}
$ClusterDatastoreWithHighestFreeSpaceGB = ($DatastoreCluster | Get-Datastore | Sort-Object FreeSpaceGB -Descending | Select-Object -First 1)
If ($ClusterDatastoreWithHighestFreeSpaceGB.FreeSpaceGB -gt $DiskTotal) {
Write-Warning ("VM DiskTotal " + $DiskTotal + "GB, will fit on " + $ClusterDatastoreWithHighestFreeSpaceGB.Name + " (" + [math]::round($ClusterDatastoreWithHighestFreeSpaceGB.FreeSpaceGB, 0) + "GB free)")
}
else {
Write-Warning ("VM DiskTotal " + $DiskTotal + "GB, will not fit on " + $ClusterDatastoreWithHighestFreeSpaceGB.Name + " (" + [math]::round($ClusterDatastoreWithHighestFreeSpaceGB.FreeSpaceGB, 0) + "GB free)")
Write-Error ("New VM " + $FQDN + " needs " + $DiskTotal + "GB of free space on a single datastore in the " + $DatastoreCluster.Name + " datastore cluster.") -ErrorAction Stop
}
$FolderLocation = $ComputeCluster | Get-Datacenter | Get-Folder -Name "_New Builds"
switch ($SPItem.OS) {
"Windows Server 2012R2 Standard (64-Bit)" { $Template = "Windows Server 2012R2 Standard" }
"Windows Server 2016 Standard (64-Bit)" { $Template = "Windows Server 2016 Standard" }
"Windows Server 2019 Standard (64-Bit)" { $Template = "Windows Server 2019 Standard" }
"Windows Server 2019 Datacenter (64-Bit)" { $Template = "Windows Server 2019 Standard" }
Default {Write-Error "Invalid template" -ErrorAction Stop}
}
$PortGroupsAvailable = Get-VDPortgroup -Server $ViServer -VDSwitch $VirtualSwitch
$PortGroup = $PortGroupsAvailable | Where-Object Name -Like ("dvPG_" + $SPItem.Vlan_Id + "*")
If (!($PortGroup)) {
Write-Error "Virtual port group not found" -ErrorAction Stop
Stop
}
If (@($PortGroup).count -gt 1) {
Write-Error "Multiple port groups found" -ErrorAction Stop
Stop
}
$NewOSSpecName = ("AutoBuild-$Hostname-" + (Get-Date -UFormat "%Y%m%d%H%M%S"))
Write-Warning "NewOSSpecName = $NewOSSpecName"
Get-OSCustomizationSpec -Name "Windows (Auto)" -Server $ViServer | New-OSCustomizationSpec -Name $NewOSSpecName -Type Persistent -Server $ViServer
Get-OSCustomizationSpec -Name $NewOSSpecName -Server $ViServer | `
Set-OSCustomizationSpec `
-NamingScheme fixed `
-NamingPrefix $Hostname `
-AdminPassword $GuestCredentialBB.GetNetworkCredential().Password
Get-OSCustomizationSpec -Name $NewOSSpecName -Server $ViServer | `
Get-OSCustomizationNicMapping | `
Set-OSCustomizationNicMapping `
-IpMode UseStaticIP `
-IpAddress $IpAddress.IPAddressToString `
-SubnetMask $SubnetMask.IPAddressToString `
-DefaultGateway $DefaultGateway.IPAddressToString `
-Dns "10.2.7.40", "10.10.10.10"
$OSSpec = Get-OSCustomizationSpec -Name $NewOSSpecName -Server $ViServer
<#
$NewVMParams = @{
Name = $FQDN;
ResourcePool = $SPItem.Cluster;
Datastore = $DatastoreCluster;
DiskStorageFormat = $DiskStorageFormat;
Template = $Template;
Location = $FolderLocation;
OSCustomizationSpec = $OSSpec;
}
$NewVMParams
New-VM @NewVMParams
#>
#Set-Location C:\Temp # required to make New-VM work, https://communities.vmware.com/thread/591294
# seems fixed on 2022/07/01
try {
Write-Warning $FQDN
Write-Warning $ComputeCluster.Name
Write-Warning $DatastoreCluster
Write-Warning $DiskStorageFormat
Write-Warning $Template
Write-Warning $FolderLocation
Write-Warning $OSSpec
New-VM -Name $FQDN -ResourcePool $ComputeCluster.Name -Datastore $DatastoreCluster -DiskStorageFormat $DiskStorageFormat -Template $Template -Location $FolderLocation -OSCustomizationSpec $OSSpec
}
catch {
Stop
Stop
}
#If (!($BuildError)) {
$VM = Get-VM -Name $FQDN
# Ensure CPU/Memory Hot-Add Enabled
$vmView = $VM | Get-View
$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$vmOptValCPU = New-Object VMware.Vim.OptionValue
$vmOptValMem = New-Object VMware.Vim.OptionValue
$vmOptValCPU.Key = "vcpu.hotadd"
$vmOptValMem.Key = "mem.hotadd"
$vmOptValCPU.Value = "true"
$vmOptValMem.Value = "true"
$vmConfigSpec.ExtraConfig += $vmOptValCPU
$vmConfigSpec.ExtraConfig += $vmOptValMem
$vmView.ReconfigVM($vmConfigSpec)
# Set CPU, Memory, Network
$VM | Set-VM -NumCpu $SPItem.Processors -MemoryGB $SPItem.RAM -Confirm:$false
$VM | Get-NetworkAdapter | Set-NetworkAdapter -Portgroup $PortGroup -Confirm:$false
# Power On VM
$VM | Start-VM
# Wait for Customization to finish
$VMStarted = $false
$VMCustomizationStarted = $false
$VMCustomizationResult = $false
While ($VMStarted -eq $false -or $VMCustomizationStarted -eq $false -or $VMCustomizationResult -eq $false) {
Write-Warning ("Customization wait loop started " + (Get-Date))
Write-Verbose "Current Status:"
Write-Verbose ("VMStarted: " + $VMStarted)
Write-Verbose ("VMCustomizationStarted: " + $VMCustomizationStarted)
Write-Verbose ("VMCustomizationResult: " + $VMCustomizationResult)
$GetVIEventRuntime = Measure-Command -Expression { $VMEvents = Get-VIEvent -Entity $VM -Server $ViServer -ErrorAction SilentlyContinue }
Write-Verbose ("Get-VIEvent last run time: " + $GetVIEventRuntime.TotalSeconds + " seconds")
If ($VMStarted -eq $false) {
If (@($VMEvents | Where-Object { $_.GetType().Name -eq "VMStartingEvent" })) {
$VMStarted = $true
Write-Warning "[$FQDN]:Virtual machine started"
}
}
If ($VMCustomizationStarted -eq $false) {
If (@($VMEvents | Where-Object { $_.GetType().Name -eq "CustomizationStartedEvent" })) {
$VMCustomizationStarted = $true
Write-Warning "[$FQDN]:Virtual machine customization started"
}
}
If ($VMCustomizationResult -eq $false) {
If (@($VMEvents | Where-Object { $_.GetType().Name -eq "CustomizationFailed" })) {
$VMCustomizationResult = $true
Write-Error "[$FQDN]:Virtual machine customization failed"
Exit
Exit
}
If (@($VMEvents | Where-Object { $_.GetType().Name -eq "CustomizationSucceeded" })) {
$VMCustomizationResult = $true
Write-Warning "[$FQDN]:Virtual machine customization completed"
}
}
}
# Delete OS Customization Spec
# Get-OSCustomizationSpec -Name $NewOSSpecName | Remove-OSCustomizationSpec -Confirm:$false
# Add/Expand Disks
Write-Warning -Message "[$FQDN]:Modify disks 1,2,3"
$VMDisk = $VM | Get-HardDisk
$VMDisk1 = $VMDisk | Where-Object Name -EQ "Hard disk 1"
$VMDisk2 = $VMDisk | Where-Object Name -EQ "Hard disk 2"
$VMDisk3 = $VMDisk | Where-Object Name -EQ "Hard disk 3"
If ($SPItem.Disk1) {
If (!$VMDisk1) {
$VM | New-HardDisk `
-CapacityGB $SPItem.Disk1 `
-StorageFormat Thin `
-DiskType Flat `
-Persistence Persistent
}
$VMDisk1 = $VM | Get-HardDisk | Where-Object Name -EQ "Hard disk 1"
If ($VMDisk1.CapacityGB -lt $SPItem.Disk1) {
Set-HardDisk -HardDisk $VMDisk1 -CapacityGB $SPItem.Disk1 -Confirm:$false
}
}
If ($SPItem.Disk2) {
If (!$VMDisk2) {
$VM | New-HardDisk `
-CapacityGB $SPItem.Disk2 `
-StorageFormat Thin `
-DiskType Flat `
-Persistence Persistent
}
$VMDisk2 = $VM | Get-HardDisk | Where-Object Name -EQ "Hard disk 2"
If ($VMDisk2.CapacityGB -lt $SPItem.Disk2) {
Set-HardDisk -HardDisk $VMDisk2 -CapacityGB $SPItem.Disk2 -Confirm:$false
}
}
If ($SPItem.Disk3) {
If (!$VMDisk3) {
$VM | New-HardDisk `
-CapacityGB $SPItem.Disk3 `
-StorageFormat Thin `
-DiskType Flat `
-Persistence Persistent
}
$VMDisk3 = $VM | Get-HardDisk | Where-Object Name -EQ "Hard disk 3"
If ($VMDisk3.CapacityGB -lt $SPItem.Disk3) {
Set-HardDisk -HardDisk $VMDisk3 -CapacityGB $SPItem.Disk3 -Confirm:$false
}
}
# skipping tag assignment for now
# Set-ITDVMwareVMTagFromSharePoint -ComputerName $FQDN -SharePointCredential $SPCred -Verbose
# Run Guest OS code
# Enable RDP with NLA - can be done with GPO
# Enable WinRM - ITD WinRM enable
# Configure Power Plan - ITD-PowerPlan-HighPerformance
# Activate Windows, KMS on-premise, Azure to Azure
# DVD Drive to Z:
# Expand C:
# Partition/Format the rest, GPT/NTFS
# Configure Page File Disk
# Enabling server manager performance monitors
# Configure Time Zone and NTP - no GPO available
# Disable Windows Firewall
# Join AD
#Initialize-ITDServer -Credential $ADCred
Write-Warning -Message "[$FQDN]:Assigning WMI Tag 000-Prod, SCCM will change it later if required"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText {
# Move DVD Drive Mount
try {
Write-Verbose "Create new Class"
$Class = New-Object System.Management.ManagementClass("root\cimv2", [String]::Empty, $null);
$Class["__CLASS"] = "ITD";
$Class.Qualifiers.Add("Static", $true)
$Class.Properties.Add("MyKey", [System.Management.CimType]::String, $false)
$Class.Properties["MyKey"].Qualifiers.Add("Key", $true)
$Class.Properties.Add("LastModified", [System.Management.CimType]::String, $false)
$Class.Properties.Add("DTAP", [System.Management.CimType]::String, $false)
$Class.Properties.Add("Baseline", [System.Management.CimType]::String, $false)
$Class.Put()
Write-Verbose "Create single ITD Object"
Set-WmiInstance -Class ITD -Arguments @{LastModified = (Get-Date); DTAP = "Prod"; Baseline = "000" }
}
catch {
Throw $_
Break
}
}
Write-Warning -Message "[$FQDN]:Checking for DVD drive..."
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText {
# Move DVD Drive Mount
try {
$dvd_letter = 'Z'
$dvd = Get-WmiObject -Class Win32_Volume -Filter "DriveType=5" | Select-Object -First 1
if ($dvd.Name -notmatch $dvd_letter) {
Write-Verbose -Message "Found DVD drive, switching to $dvd_letter`:"
Set-WmiInstance -InputObject $dvd -Arguments @{DriveLetter = "$dvd_letter`:" } | Out-Null
Write-Verbose -Message "DVD drive moved to drive letter $dvd_letter`:"
}
else {
Write-Verbose -Message "No DVD drive changes required, continuing..."
}
}
catch {
Throw $_
Break
}
}
Write-Warning -Message "[$FQDN]:Checking for unpartitioned space on C: disk..."
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText {
# Expand C: Partition To Maximum Extent
try {
$cSize = ( Get-Partition -DriveLetter C ).Size
$cMaxSize = ( Get-PartitionSupportedSize -DriveLetter C ).SizeMax
if ($cSize -lt $cMaxSize) {
Write-Verbose -Message "Expanding C: from $($csize / 1GB)GB to $($cMaxSize / 1GB)GB..."
Resize-Partition -DriveLetter C -Size $cMaxSize
Write-Verbose -Message "C: expanded to $($cMaxSize / 1GB)GB."
}
else {
Write-Verbose -Message "C: is already at maximum size, continuing..."
}
}
catch {
Throw $_
Break
}
}
Write-Warning "[$FQDN]:Start Extra Disk(s) config"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText {
# Initialize Additional Disks
try {
# Non-initialized and MBR-initialized disks will have 0 partitions by default, but GPT-initialized disks will have 1 system reserved partition by default
$disks = Get-Disk | Where-Object { $_.NumberOfPartitions -eq 0 -or ( $_.PartitionStyle -eq 'GPT' -and $_.NumberOfPartitions -eq 1 ) } | Sort-Object -Property Number
if ($disks) {
Write-Verbose -Message "Found $(@($disks).Count) unpartitioned disks."
# Prevent the "You must format this partition before using it." popup
if (Get-Service ShellHWDetection -ErrorAction SilentlyContinue) { Stop-Service ShellHWDetection -ErrorAction SilentlyContinue }
foreach ($disk in $disks) {
if ($disk.IsOffline) {
Set-Disk $disk.Number -IsOffline $false
Write-Verbose -Message "Brought disk $($disk.Number)($("{0:n0}GB" -f ($disk.Size / 1GB))) online..."
}
if ($disk.IsReadOnly) { Set-Disk $disk.Number -IsReadOnly $false }
if ($disk.PartitionStyle -eq 'RAW') { Initialize-Disk $disk.Number -PartitionStyle GPT -ErrorAction SilentlyContinue }
$diskParam = @{
FileSystem = 'NTFS'
Confirm = $false
}
$driveLetter = [Int][Char]'D'
while (Get-Volume -DriveLetter $([Char]$driveLetter) -ErrorAction SilentlyContinue) {
$driveLetter++
}
$diskParam.DriveLetter = [Char]$driveLetter
if (@($disks).IndexOf($disk) -eq 0 -and (-not (Get-Volume -DriveLetter D -ErrorAction SilentlyContinue))) {
$diskParam.NewFileSystemLabel = 'Temporary Storage'
}
elseif (@($disks).IndexOf($disk) -eq 1 -and (-not (Get-Volume -DriveLetter E -ErrorAction SilentlyContinue))) {
$diskParam.NewFileSystemLabel = 'Data'
}
[void](New-Partition -DiskNumber $disk.Number -DriveLetter $diskParam.DriveLetter -UseMaximumSize)
[void](Format-Volume @diskParam)
}
}
else {
Write-Verbose -Message "No unpartitioned disks found, continuing..."
}
}
catch {
Throw $_
Break
}
finally {
if (Get-Service ShellHWDetection -ErrorAction SilentlyContinue) { Start-Service ShellHWDetection -ErrorAction SilentlyContinue }
}
}
Write-Warning "[$FQDN]:Start Page File Configuration"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText {
# Configure Page File
if (Get-Partition -DriveLetter D -ErrorAction SilentlyContinue) {
Write-Verbose -Message "Setting up pagefile.sys on D:..."
try {
if (-not [IO.File]::Exists('D:\pagefile.sys')) {
$autoPage = Get-WmiObject -Class Win32_ComputerSystem -EnableAllPrivileges
$autoPage.AutomaticManagedPagefile = $false
[void]$autoPage.Put()
Write-Verbose -Message "Disabled automatic pagefile management."
$pageFile = Get-WmiObject -Class Win32_PageFileSetting -EnableAllPrivileges
$pageFile.Delete()
Write-Verbose -Message "Deleted C:\pagefile.sys."
Set-WmiInstance -Class Win32_PageFileSetting -Arguments @{ Name = "D:\pagefile.sys"; InitialSize = 0; MaximumSize = 0; } -EnableAllPrivileges | Out-Null
Write-Verbose -Message "System managed page file created on D:\pagefile.sys."
}
else {
Write-Verbose -Message "Pagefile already configured on D:, continuing..."
}
}
catch {
Throw $_
Break
}
}
else {
Write-Verbose -Message "Page file drive not found, cannot set up page file. Continuing server configuration..."
Write-Warning "Page file drive not found, cannot set up page file. Continuing server configuration..."
}
}
Write-Warning -Message "[$FQDN]:Enabling Remote Management..."
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText {
# Configure Remote Management (RDP/PoSH)
try {
Write-Verbose -Message "Checking WinRM..."
if (Test-WSMan -ErrorAction SilentlyContinue) {
Write-Verbose -Message "WinRM is already enabled."
}
else {
Enable-PSRemoting -Force
Write-Verbose -Message "WinRM is now enabled."
}
Write-Verbose -Message "Checking RDP..."
$RDP = Get-WmiObject Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices
$NLA = Get-WmiObject Win32_TSGeneralSetting -Namespace root\cimv2\TerminalServices -Filter "TerminalName='RDP-tcp'"
if ($RDP.AllowTSConnections -eq 0) {
Write-Verbose -Message "RDP is disabled, enabling..."
$RDP.SetAllowTSConnections(1, 1) | Out-Null
Write-Verbose -Message "RDP is enabled."
}
else {
Write-Verbose -Message "RDP is already enabled, checking NLA security..."
}
if ($NLA.UserAuthenticationRequired -eq 0) {
Write-Verbose -Message "RDP is not NLA secured, enabling..."
$NLA.SetUserAuthenticationRequired(1) | Out-Null
Write-Verbose -Message "RDP is now NLA secured."
}
else {
Write-Verbose -Message "RDP is already NLA secured."
}
}
catch {
Throw $_
Break
}
}
Write-Warning -Message "[$FQDN]:Checking current power plan..."
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText {
# Configure Power Plan
try {
$powerPlans = powercfg -l
if ($powerPlans -match '\*$' -notmatch 'High performance') {
$currentPlan = [regex]::Match($powerPlans, '(?<=(\())[^)]+(?=(\)\s\*))').Value
Write-Verbose -Message "Power plan is currently set to $currentPlan, changing to High Performance..."
$highPerformance = [regex]::Match($powerPlans, '([\d\w-\S]+)(?=\s+\(High performance\))').Value
[void](powercfg -setactive $highPerformance)
Write-Verbose -Message "Power plan set to High Performance."
}
else {
Write-Verbose -Message "Power plan already configured for High Performance."
}
[void](& w32tm.exe /resync /nowait)
}
catch {
Throw $_
Break
}
}
$TimeSyncFunc = {
# Configure Time/Date Settings
Write-Verbose -Message "Checking current time/date settings..."
$Domain = "<DomainName>"
try {
if ((Get-TimeZone).Id -ne 'Central Standard Time') {
Write-Verbose -Message "Current time zone set to $((Get-TimeZone).Id), setting to Central Standard Time."
Set-TimeZone -Id 'Central Standard Time'
Write-Verbose -Message "Time zone set to Central Standard Time."
}
else {
Write-Verbose -Message "Time zone is already set to Central Standard Time."
}
<#
Write-Verbose -Message "Beginning a time synchronization..."
if ((Get-Service W32Time).Status -eq 'Stopped') {
Start-Service W32Time
}
[void](& w32tm.exe /config /manualpeerlist:$Domain /syncfromflags:all /update)
[void](& w32tm.exe /resync /nowait)
# Start background job to check time service
$tmJob = Start-Job -Name 'ManualTimeSync' -ScriptBlock {
do {
$tmOut = & w32tm.exe /query /status /verbose
Start-Sleep -Seconds 10
} until($tmOut -match '^Last Sync Error: 0\D+$')
}
# If after three minutes time still has not synched, move on. This usually causes no problems.
if ((Wait-Job -Job $tmJob -Timeout 180).State -eq 'Completed') {
Write-Warning -Message "Time synchronization with $($Domain.ToLower()) successful."
}
else {
[void](Stop-Job -Job $tmJob)
Write-Warning -Message "Time synchronization with $($Domain.ToLower()) failed."
}
#>
}
catch {
Throw $_
Break
}
}
$TimeSyncScriptBlock = $TimeSyncFunc -replace '<DomainName>', $DomainName
$VM | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText $TimeSyncScriptBlock
#>
Write-Warning -Message "[$FQDN]:Enabling the server manager performance monitors..."
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText {
# Enable Performance Counters
try {
if (Get-ScheduledTask -TaskName "Server Manager Performance Monitor" | Where-Object State -NE "Running" -ErrorAction SilentlyContinue) {
Enable-ScheduledTask -TaskPath "\Microsoft\Windows\PLA\" -TaskName "Server Manager Performance Monitor" | Start-ScheduledTask
Write-Verbose -Message "Performance monitors enabled."
}
else {
Write-Verbose -Message "Performance monitors already enabled, continuing..."
}
}
catch {
Throw $_
Break
}
}
Write-Warning -Message "[$FQDN]:Disable Windows Firewall"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText {
# Disable Windows Firewall
Write-Verbose -Message "Checking for active Windows Firewall..."
if ((Get-NetFirewallProfile).Enabled -contains 'True') {
Write-Verbose -Message "Windows Firewall is still enabled, disabling it..."
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled False
Write-Verbose -Message "Windows Firewall disabled."
}
else {
Write-Verbose -Message "Windows Firewall already disabled, continuing..."
}
}
# Active Directory
Write-Warning "[$FQDN]:Join Active Directory (if required)"
$DomainName = $FQDN.Substring($FQDN.IndexOf(".") + 1)
$AppName = $SPItem.AppName
switch ($DomainName) {
'nd.gov' {
$SearchBaseDomain = "dc=nd,dc=gov"
}
'ndcloud.gov' {
$SearchBaseDomain = "dc=ndcloud,dc=gov"
}
}
If ($DomainName -eq "nd.gov") {
$OUAppName = Get-ADOrganizationalUnit -Server $DomainName -SearchBase ("OU=SERVERS,ou=COMPUTERS,ou=ITD," + $SearchBaseDomain) -Filter { Name -eq $AppName }
If (!($OUAppName)) {
$OUAppName = Get-ADOrganizationalUnit -SearchBase ("OU=SERVERS,ou=COMPUTERS,ou=ITD," + $SearchBaseDomain) -Filter { Name -eq 'All-General' }
}
$ExistingADComputer = Get-ADComputer -Filter { Name -eq $Hostname }
If ($ExistingADComputer) {
If ($ExistingADComputer.DistinguishedName -like ("*" + $SPItem.AppName + "*") -or $ExistingADComputer.DistinguishedName -like "*All-General*") {
Write-Warning "AD object already exists, OU path does match"
$OuFinal = $ExistingADComputer.DistinguishedName -replace '^.+?(?<!\\),', ''
}
Else {
Write-Error "AD object already exists, OU path mismatch"
Exit
Exit
}
}
Else {
switch ($SPItem.Environment) {
'Test' {
If ($AppName -like "Shared-Peoplesoft*") { $EnvString = "Non-Prod" }
Else { $EnvString = "Test" }
$OuAppNameEnv = Get-ADOrganizationalUnit -SearchBase $OUAppName.DistinguishedName -Filter * | Where-Object Name -Like "*$EnvString*"
}
'Production' {
$EnvString = "Prod"
$OuAppNameEnv = Get-ADOrganizationalUnit -SearchBase $OUAppName.DistinguishedName -Filter * | Where-Object Name -Like "*$EnvString*"
}
}
If ($OuAppNameEnv) { $OUFinal = $OUAppNameEnv.DistinguishedName }
Else { $OuFinal = $OUAppName.DistinguishedName }
#New-ADComputer -Name $HostName.ToUpper() -Path $OUFinal -Credential $ADCred -Description ($SPItem | Select-Object AppName, Environment | ConvertTo-Json)
}
$FirstScriptBlock = { $DomainJoinCred = New-Object System.Management.Automation.PSCredential('svcitdvmdomainjoin', ('hypes-Vgv8h89' | ConvertTo-SecureString -AsPlainText -Force)) }
$SecondScriptText = 'Add-Computer -DomainName <DomainName> -OUPath "<OuPath>" -Credential $DomainJoinCred'
$SecondScriptText = $SecondScriptText -replace '<DomainName>', $DomainName
$SecondScriptText = $SecondScriptText -replace '<OuPath>', $OuFinal
$SecondScriptText = $SecondScriptText -replace '<OuPath>', ("OU=SERVERS,ou=COMPUTERS,ou=ITD," + $SearchBaseDomain)
Write-Warning -Message "[$FQDN]:Invoke-VMScript to AD join"
$InvokeVMScriptFunc = [System.Management.Automation.ScriptBlock]::Create("$FirstScriptBlock ; $SecondScriptText")
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredential -ScriptType PowerShell -ScriptText $InvokeVMScriptFunc
Write-Warning -Message "[$FQDN]:Restart VMGuest, wait for Tools, then 90 seconds after"
Get-VM -Name $FQDN | Restart-VMGuest -Confirm:$false
Wait-Tools -VM (Get-VM -Name $FQDN)
Start-Sleep -Seconds 90
}
Write-Warning ("[$FQDN]:Copying SCCM client installer to C:\temp... " + (Get-Date))
Copy-VMGuestFile -Source D:\SCCM_Client\ -Destination C:\temp\SCCM_Client -VM (Get-VM -Name $FQDN) -LocalToGuest -GuestCredential $GuestCredentialAB -Force
Write-Warning ("[$FQDN]:SCCM client copy complete " + (Get-Date))
#E:\AutoBuild\SCCM_Client\
# Check if SCCM automatically installed the SCCM client and registered it
$CcmRegistered = $false
$CcmRegistration = Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
Get-Content C:\windows\ccm\logs\ClientIDManagerStartup.log
}
If ($CcmRegistration.ScriptOutput -match "Client is registered") {
Write-Warning "Client is registered."
$CcmRegistered = $true
}
ElseIf ($CcmRegistration.ScriptOutput -match "Client is already registered") {
Write-Warning "Client is already registered."
$CcmRegistered = $true
}
If ($CcmRegistered -eq $false) {
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
If (Get-Process -Name ccmsetup -ErrorAction SilentlyContinue) {
Write-Warning "CCM client is already installing"
$CcmRegistered = $true
}
ElseIf (Get-Process -Name ccmexec -ErrorAction SilentlyContinue) {
Write-Warning "CCM client is already installed"
$CcmRegistered = $true
}
Else {
Write-Warning -Message "Installing SCCM Client..."
Invoke-Expression -Command "C:\temp\SCCM_Client\ccmsetup.exe SMSSITECODE=ITD SMSMP=itdsccmp2.nd.gov DNSSUFFIX=nd.gov"
}
}
}
Write-Warning "[$FQDN]:Register SCCM Client"
While ($CcmRegistered -eq $false) {
$CcmRegistration = Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
Get-Content C:\windows\ccm\logs\ClientIDManagerStartup.log
}
If ($CcmRegistration.ScriptOutput -match "Client is registered") {
Write-Warning "Client is registered."
$CcmRegistered = $true
}
ElseIf ($CcmRegistration.ScriptOutput -match "Client is already registered") {
Write-Warning "Client is already registered."
$CcmRegistered = $true
}
ElseIf ($CcmRegistered -eq $false) { Start-Sleep -Seconds 30 }
}
Write-Warning -Message "[$FQDN]:Approve SCCM Client"
#Start-Sleep -Seconds 30 # ADD LOOP/SMARTS TO WAIT FOR DISCOVERY AND ANOTHER FOR APPROVAL
Invoke-Command -ComputerName itdsccmp2.nd.gov -Credential $CcmCred -ArgumentList $Hostname -ScriptBlock {
Import-Module 'D:\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
$PSDrives = Get-PSDrive
If ($PSDrives | Where-Object Name -EQ "ITD") {
# ITD Drive exists, do nothing
}
else {
New-PSDrive -Name "ITD" -PSProvider AdminUI.PS.Provider\CMSite -Root itdsccmp2.nd.gov
}
Set-Location ITD:\
$Device = Get-CMDevice -Name $args[0]
If ($Device.IsApproved -eq 0) {
Approve-CMDevice -DeviceName $args[0]
}
}
Write-Warning "[$FQDN]:Trigger SCCM MachinePolicy First Check-in"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
[void] ([wmiclass] "\\localhost\root\ccm:SMS_Client").TriggerSchedule("{00000000-0000-0000-0000-000000000021}");
}
Write-Warning "[$FQDN]:Trigger SCCM MachinePolicy"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
[void] ([wmiclass] "\\localhost\root\ccm:SMS_Client").TriggerSchedule("{00000000-0000-0000-0000-000000000021}");
}
#Start-Sleep -Seconds 180
Write-Warning -Message '[$FQDN]:Waiting for network connectivity / Then KVM Activation...'
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
# Pause until network connectivity is available
$KMS = 'kms.nd.gov'
try {
$nwJob = Start-Job -Name 'NetworkCheck' -ScriptBlock {
Param ( [String]$KMS )
do {
$nwStatus = Test-NetConnection -ComputerName $KMS -Port 1688 -InformationLevel Quiet
Start-Sleep -Seconds 10
} until($nwStatus)
} -ArgumentList $KMS
# If after 30 seconds the network connection is not responding continue on
if ((Wait-Job -Job $nwJob -Timeout 30).State -eq 'Completed') {
Write-Verbose -Message 'Network connectivity has been verified.'
}
else {
[void](Stop-Job -Job $nwJob)
Write-Verbose -Message 'Network connectivity could not be verified.'
}
}
catch {
Throw $_
Break
}
# Activate via KMS
Write-Verbose -Message "Activating windows against $KMS..."
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit
}
try {
cscript C:\Windows\System32\slmgr.vbs /skms $KMS | Out-Null
cscript C:\Windows\System32\slmgr.vbs /ato | Out-Null
Write-Verbose -Message "Checking activation status..."
$kmsOut = cscript C:\Windows\System32\slmgr.vbs /dli
if (($kmsOut | Select-String -Pattern '^License Status:') -match 'Licensed') {
Write-Verbose -Message "Windows successfully activated."
}
else {
Write-Verbose -Message "Windows failed to activate, run slmgr commands manually. Ensure server time is correct."
Write-Warning -Message "Windows failed to activate, run slmgr commands manually. Ensure server time is correct."
}
}
catch {
Throw $_
Break
}
}
Write-Warning "[$FQDN]:End"
}
+22
View File
@@ -0,0 +1,22 @@
$ITD = 'HAKpueFYU4L3NMXTKqtHssnNGBrew3gVRLEq2Yi7yzWW8fpKNCPB5gUcnHfr9sdhXC53y7gWf5BDtxXkr3mZA3NV7DszpR3kjiLgi3FpRPgUWus9ZxCWy63znqPGh3AJ2bn43uP7GjzfLcgqYLQRkir'
$URL = 'https://s1events.azure-automation.net/webhooks?token=VfxwwkSMqH4yiLrWmUfVowEuXBWgkbcBDeX8FFwMbCI%3d'
$header = @{ITD=$ITD}
$params = @(
@{
Id = 1986;
SnapshotDuration = 3;
DateTime = '2019-07-29T19:00:00Z';
Title = "itdscmt1.nd.gov";
Email = "zmeier@nd.gov";
}
)
$body = ConvertTo-Json -InputObject $params
$response = Invoke-WebRequest -Method Post -Uri $URL -Headers $header -Body $body
[System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId( `
(Get-Date), 'Central Standard Time')
[System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId((Get-Date), 'Central Standard Time')
+41
View File
@@ -0,0 +1,41 @@
$ServerList = @"
itdmdnvm-test01.nd.gov
itdmdnvm-test02.nd.gov
itdmdnvm-test03.nd.gov
"@
$ServerList = ConvertTo-Array -MultiLineString $ServerList
$VMHosts = Get-VMHost $ServerList | sort-object Name
$x = ForEach($VMHost in $VMHosts){
$EsxCli = $VMHost | Get-EsxCli -V2
#$StaticRouteBefore =
$EsxCli.network.ip.route.ipv4.list.Invoke()
<#
Gateway : 10.2.168.241
Interface : vmk2
Netmask : 255.255.255.192
Network : 10.2.169.128
Source : MANUAL
#>
#$PhysicalAdapter = $VMHost | Get-VMHostNetworkAdapter | where-object {$_.Name -eq "vmnic6" -and $_.Name -eq "vmnic7"}
#$dvSwitch = Get-VDSwitch -Name dvSwitch-TSTMGMT1-Backup
<#
$PortGroup = Get-VDPortGroup -Name dvPG_3532_10.2.168.240_28
$DNSRecord = Resolve-DnsName -Name ($VMHost.Name.split('.')[0] + 'co.' + $VMHost.Name.split('.')[1] + '.' + $VMHost.Name.split('.')[2])
$VMHost | New-VMHostNetworkAdapter -PortGroup $PortGroup `
-VirtualSwitch $dvSwitch `
-IP $DNSRecord.IPAddress `
-SubnetMask 255.255.255.240 `
-ManagementTrafficEnabled $true
#>
#$params = @{
# network = '10.2.168.128/26'
#}
#$EsxCli.network.ip.route.ipv4.add
}
+31
View File
@@ -0,0 +1,31 @@
$Datacenters = Get-Datacenter -Name Primary*, Secondary*
ForEach ($Datacenter in $Datacenters) {
write-warning -Message $Datacenter.name
$DatacenterName = $Datacenter.Name
$Datastores = $Datacenter | Get-Datastore -Name *FS92*
$result = [System.Collections.ArrayList]@()
ForEach ($Datastore in $Datastores) {
write-warning -Message $Datastore.name
$VMsOnDatastore = $null
$VMsOnDatastore = $Datastore | Get-VM
$VMDKsOnDatastore = $VMsOnDatastore | Get-HardDisk | Where-Object Filename -Match $Datastore.Name
$obj = [PSCustomObject]@{
'DatastoreName' = $Datastore.Name;
'UsedSpaceGB' = [math]::round($Datastore.CapacityGB - $Datastore.FreeSpaceGB, 2);
#'FreeSpaceGB' = [math]::round($Datastore.FreeSpaceGB, 2);
'CapacityGB' = [math]::round($Datastore.CapacityGB, 2);
'PercentUsed' = [math]::round(($Datastore.CapacityGB - $Datastore.FreeSpaceGB) / $Datastore.CapacityGB, 2);
#'VMUsedSpaceGB' = [math]::round(($VMsOnDatastore | Measure-Object -Sum UsedSpaceGB).Sum, 2);
#'VMProvisionedGB' = [math]::round(($VMsOnDatastore | Measure-Object -Sum ProvisionedSpaceGB).Sum, 2);
#'VMPercentUsed' = [math]::round(($VMsOnDatastore | Measure-Object -Sum UsedSpaceGB).Sum / ($VMsOnDatastore | Measure-Object -Sum ProvisionedSpaceGB).Sum , 2);
}
$null = $result.Add($obj)
}
$Date = Get-Date -UFormat %Y%m%d
$result | Export-Csv -Path "D:\State of North Dakota\-Tm-ITD-Virtualization - Documents\FS9200 Overprovision Fixes\FS9200-$DatacenterName-$Date.csv"
}
+119
View File
@@ -0,0 +1,119 @@
function Set-AlarmActionState {
<#
.SYNOPSIS Enables or disables Alarm actions
.DESCRIPTION The function will enable or disable
alarm actions on a vSphere entity itself or recursively
on the entity and all its children.
.NOTES Author: Luc Dekens
.PARAMETER Entity
The vSphere entity.
.PARAMETER Enabled
Switch that indicates if the alarm actions should be
enabled ($true) or disabled ($false)
.PARAMETER Recurse
Switch that indicates if the action shall be taken on the
entity alone or on the entity and all its children.
.EXAMPLE
PS> Set-AlarmActionState -Entity $cluster -Enabled:$true
#>
param(
[CmdletBinding()]
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$Entity,
[switch]$Enabled,
[switch]$Recurse
)
begin{
$alarmMgr = Get-View AlarmManager
}
process{
if($Recurse){
$objects = @($Entity)
$objects += Get-Inventory -Location $Entity
}
else{
$objects = $Entity
}
$objects | %{
$alarmMgr.EnableAlarmActions($_.Extensiondata.MoRef,$Enabled)
}
}
}
function Get-ITDVMwareAlarmActionState
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$Entity,
[switch]$Recurse = $false
)
process {
$Entity = Get-Inventory -Id $Entity.Id
if($Recurse){
$objects = @($Entity)
$objects += Get-Inventory -Location $Entity
}
else{
$objects = $Entity
}
$objects |
Select Name,
@{N="Type";E={$_.GetType().Name.Replace("Impl","").Replace("Wrapper","")}},
@{N="Alarm actions enabled";E={$_.ExtensionData.alarmActionsEnabled}}
}
}
<#
.SYNOPSIS
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
function Get-ITDVMwareAlarmActionState
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$Entity,
[switch $Enabled,
[switch]$Recurse
)
begin
{
}
process
{
}
end
{
}
}
+20
View File
@@ -0,0 +1,20 @@
$VMs = Get-VM | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
$result = [System.Collections.ArrayList]@()
ForEach ($VM in $VMs) {
$Disks = $VM | Get-HardDisk
$TotalThreads = $Disks.count
$256GBDisks = ($Disks | where-object CapacityGB -gt 256)
$obj = [PSCustomObject]@{
'ComputerName' = $VM.Name;
'NumOfDisks' = $Disks.count
'NumOver256GB' = $256GBDisks.count
#'NumOf256GBThreads' = $TotalThreads
}
#Write-Output $obj
$null = $result.Add($obj)
}
$result
+21
View File
@@ -0,0 +1,21 @@
[string]$Cluster_str = "WINDOWS1"
#ForEach ($Cluster_str in (Get-Cluster | Sort-object Name).Name) {
Write-Warning $Cluster_str
$x=Get-View -ViewType ClusterComputeResource -Property Name, Summary -Filter @{"Name" = $Cluster_str } | Foreach-Object {
$viewThisCluster = $_
Get-View -ViewType VirtualMachine -Property Name, Runtime.PowerState, Summary.Runtime.MinRequiredEVCModeKey -SearchRoot $viewThisCluster.MoRef | Foreach-Object {
$z = $_
New-Object -Type PSObject -Property ([ordered]@{
Name = $_.Name
PowerState = $_.Runtime.PowerState
VMEVCMode = $_.Summary.Runtime.MinRequiredEVCModeKey
ClusterEVCMode = $viewThisCluster.Summary.CurrentEVCModeKey
ClusterName = $viewThisCluster.Name
#VMHost = (Get-VM $_.Name | Get-VMHost).Name
})
}
}
#}
$x | where-object { $_.VMEVCMode -eq 'intel-broadwell' -or $_.VMEVCMode -eq 'intel-haswell' } | Format-Table
+20
View File
@@ -0,0 +1,20 @@
$import = import-csv D:\VMsToFix.csv #| where-object Name -eq itdvmvc1script.nd.gov
Get-VM ($import).Name | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" } | Stop-VMGuest -Confirm:$false
ForEach($VM in $import){
Get-VM $VM.Name | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" } | Stop-VMGuest -Confirm:$false
}
# status check
Get-VM -Name ($import).Name | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" } | group-object PowerState
# report
Get-VM -Name ($import).Name | Select Name,PowerState,NumCpu,CoresPerSocket -ov BeforeChange
$BeforeChange | Export-Csv "D:\BeforeChange.csv"
Get-VM -Name ($import).Name | Set-VM -CoresPerSocket 1 -Confirm:$false
Get-VM -Name ($import).Name | Select Name,PowerState,NumCpu,CoresPerSocket
#Get-VM -Name ($import).Name | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" } | Start-VM
+16
View File
@@ -0,0 +1,16 @@
$Clusters = get-datacenter Primary*, Secondary* | get-cluster | sort-object Name
$Clusters | ForEach-Object{
$_ | Set-Cluster -HAEnabled $false -DrsEnabled $false -Confirm:$false
}
$Clusters = get-datacenter Primary*, Secondary* | get-cluster | sort-object Name
$Clusters | ForEach-Object{
If($_.Name -like "AVAYA*" -or $_.Name -like "TEL*"){
$_ | Set-Cluster -HAEnabled $true -Confirm:$false
}
Else{
$_ | Set-Cluster -HAEnabled $true -DrsEnabled $true -Confirm:$false
}
}
#avaya/tel no DRS
+20
View File
@@ -0,0 +1,20 @@
# vMotion Switch
Get-VDSwitch dvSwitch-TEST2-vMotion | Add-VDSwitchVMHost -VMHost itdvmmdntest06.nd.gov -Confirm:$false
$physicalNIC = Get-VMHost itdvmmdntest06.nd.gov | Get-VMHostNetworkAdapter -Physical -Name vmnic4,vmnic5
Get-VDSwitch dvSwitch-TEST2-vMotion | Add-VDSwitchPhysicalNetworkAdapter -VMHostPhysicalNic $physicalNIC
Get-VMHost itdvmmdntest06.nd.gov | New-VMHostNetworkAdapter -VirtualSwitch dvSwitch-TEST2-vMotion -PortGroup dvPG_3637_10.2.136.128_26_kernel -confirm:$false
Get-VMHost itdvmmdntest06.nd.gov | Get-VMHostNetworkAdapter -VMKernel -Name vmk1 | Set-VMHostNetworkAdapter -IP 10.2.136.159 -SubnetMask 255.255.255.192 -VMotionEnabled $true -confirm:$false
# Data-Server
Get-VDSwitch dvSwitch-TEST2-Data-Server | Add-VDSwitchVMHost -VMHost itdvmmdntest06.nd.gov -Confirm:$false
$physicalNIC = Get-VMHost itdvmmdntest06.nd.gov | Get-VMHostNetworkAdapter -Physical -Name vmnic6,vmnic7 -confirm:$false
Get-VDSwitch dvSwitch-TEST2-Data-Server | Add-VDSwitchPhysicalNetworkAdapter -VMHostPhysicalNic $physicalNIC -confirm:$false
# Backup
Get-VDSwitch dvSwitch-TEST2-Backup | Add-VDSwitchVMHost -VMHost itdvmmdntest06.nd.gov -Confirm:$false
$physicalNIC = Get-VMHost itdvmmdntest06.nd.gov | Get-VMHostNetworkAdapter -Physical -Name vmnic8,vmnic9
Get-VDSwitch dvSwitch-TEST2-Backup | Add-VDSwitchPhysicalNetworkAdapter -VMHostPhysicalNic $physicalNIC -confirm:$false
Get-VMHost itdvmmdntest06.nd.gov | New-VMHostNetworkAdapter -VirtualSwitch dvSwitch-TEST2-Backup -PortGroup dvPG_3532_10.2.168.240_28 -confirm:$false
Get-VMHost itdvmmdntest06.nd.gov | Get-VMHostNetworkAdapter -VMKernel -Name vmk2 | Set-VMHostNetworkAdapter -IP 10.2.168.246 -SubnetMask 255.255.255.240 -confirm:$false
+36
View File
@@ -0,0 +1,36 @@
$iLOs = Find-HPEiLO -Range "10.8.144.0-255"
$iLOs += Find-HPEiLO -Range "10.8.145.0-255"
$iLOs += Find-HPEiLO -Range "10.8.146.0-255"
$iLOs += Find-HPEiLO -Range "10.8.147.0-255"
$iLOs += Find-HPEiLO -Range "10.8.148.0-255"
$iLOs += Find-HPEiLO -Range "10.8.149.0-255"
$iLOs += Find-HPEiLO -Range "10.8.150.0-255"
$iLOs += Find-HPEiLO -Range "10.8.151.0-255"
$iLOs = Find-HPEiLO -Range "10.8.144-151" -Full
$ilos | export-csv "D:\OneDrive - State of North Dakota\iLOs.csv"
$Connection = $iLOs | Connect-HPEiLO -Credential $AdminCred
$AllTags = Get-HPEiLOAssetTag -Connection $Connection
$result = @()
ForEach($ilo in $iLOs)
{
$Hostname = $ilo.hostname -replace 'lo'
$VMhost = Get-VMhost $Hostname
$obj=[PSCustomObject]@{
Hostname = $Hostname;
IPAddress = (Resolve-DNSName $Hostname).IPAddress
Model = $iLO.HostSystemInformation.SPN;
SerialNumber = $iLO.HostSystemInformation.SerialNumber;
AssetTag = ($AllTags | where-object Hostname -eq $iLO.Hostname).AssetTag;
Rack = $ilo.BladeSystem.Manager.Rack;
Enclosure = $ilo.BladeSystem.Manager.Enclosure;
Bay = $ilo.BladeSystem.Bay;
CPU = $VMhost.NumCpu;
Memory = [math]::round($VMhost.MemoryTotalGB,2);
Cluster = ($VMHost | Get-Cluster).Name;
}
$result += $obj
}
+25
View File
@@ -0,0 +1,25 @@
$AllVMHosts = Get-VMHost
$Result = [System.Collections.ArrayList]@()
ForEach($VMHost in $AllVMHosts){
$EsxCli = $VMHost | Get-EsxCli -V2
$obj = [PSCustomObject]@{
Name = $VMHost.Name;
SerialNumber = $EsxCli.hardware.platform.get.Invoke().SerialNumber;
AssetNumber = ($VMhost.ExtensionData.Summary.Hardware.OtherIdentifyingInfo | select IdentifierValue,@{n='Label';e={$_.IdentifierType.Label}} | where-object Label -eq "Asset Tag")."Asset Tag";
Model = $VMHost.Model;
CPU = $VMHost.ProcessorType;
CPU_ClockGHz = $VMHost.ProcessorType.split('@ ')[1] -replace 'GHz';
CPU_Sockets = $VMHost.Extensiondata.Summary.Hardware.NumCpuPkgs;
CPU_TotalCores = $VMHost.Extensiondata.Summary.Hardware.NumCpuCores;
MemoryTotalGB = $VMHost.MemoryTotalGB
Location = '';
Enclosure = '';
}
$null = $Result.Add($obj)
}
$Result | Export-Csv "C:\users\zmeier\desktop\hostinventory.csv"
+27
View File
@@ -0,0 +1,27 @@
$OvConnections = Connect-OVMgmt -Hostname itdbissyncompp1.nd.gov -Credential $PrvCred -AuthLoginDomain nd.gov -LoginAcknowledge
Connect-ITDvCenter -Credential $PrvCred
$OvServers = Get-OVServer
ForEach ($OvServer in $OvServers) {
$VMHost = $null
$VMHost = Get-VMHost -Name ($OvServer.serverName)
$ViServer = $VMHost.Uid.split('@')[1].split(':')[0]
If ($VMHost) {
$OldTag = Get-TagAssignment -Entity $VMHost -Category "HPE Enclosure"
$NewTag = Get-Tag -Category "HPE Enclosure" -Name $OvServer.Name.split('_')[0] -Server $ViServer
If ($OldTag.Tag -eq $NewTag) {
Write-Warning "$VMhost tag correct"
}
else {
Write-Warning "$VMhost tag incorrect, fixing"
Get-TagAssignment -Entity $VMHost -Category "HPE Enclosure" | Remove-TagAssignment -Confirm:$false -ErrorAction SilentlyContinue
$VMHost | New-TagAssignment -Tag $NewTag
}
}
Else {
Write-Warning "vmhost error"
}
}
+37
View File
@@ -0,0 +1,37 @@
$VMs = Get-DatastoreCluster WINDOWS1* | Get-Datastore | Get-VM
$VMInfo = $VMs | Select Name, @{n='ProvisionedSpaceGBr';e={[math]::round($_.ProvisionedSpaceGB,2)}}, @{n='UsedSpaceGBr';e={[math]::round($_.UsedSpaceGB,2)}}, @{n = 'IndPer'; e = { If (($_ | get-harddisk | where-object Persistence -eq IndependentPersist).count -gt 0) { $true }Else { $false } } }, @{n='Datastore';e={($_ | Get-HardDisk).Filename.split(' ')[0]}}
$IndPerVMs = $VMInfo | where-object name -ne "itdhpnvid.nd.gov" | where-object IndPer -eq $true | measure-object -Sum ProvisionedSpaceGBr, UsedSpaceGBr
$PersistVMs = $VMInfo | where-object name -ne "itdhpnvid.nd.gov" | where-object IndPer -eq $false | measure-object -sum ProvisionedSpaceGBr, UsedSpaceGBr
# manual sort data
$VMInfo | where-object Name -ne itdhpnvid.nd.gov | where-object IndPer -eq $true | sort-object UsedSpaceGBr -Descending | ft
# i don't remember specifics why this exists:
$result=@()
$VMs | ForEach-Object{
$disks = $_ | Get-HardDisk | select *,@{n='Datastore';e={$_.Filename.split(' ')[0]}}
$obj=[PSCustomObject]@{
Name = $_.Name;
Count = @($disks.Datastore | select -unique).count;
Datastores = $disks.Datastore | select -unique;
}
$result += $obj
}
$result
$BisSQLVMs=[System.Collections.ArrayList]@()
$BisSQLVMs += Get-DatastoreCluster WINDOWS1* | Get-VM -Tag 'SQL MSDN' -Server itdvmvc1.nd.gov | where-object Name -ne 'itdhpnvid.nd.gov' | sort-object Name
$BisSQLVMs += Get-DatastoreCluster WINDOWS1* | Get-VM -Tag 'SQL Enterprise Academic' -Server itdvmvc1.nd.gov | where-object Name -ne 'itdhpnvid.nd.gov' | sort-object Name
$BisSQLVMs += Get-DatastoreCluster WINDOWS1* | Get-VM -Tag 'SQL Standard' -Server itdvmvc1.nd.gov | where-object Name -ne 'itdhpnvid.nd.gov' | sort-object Name
$BisSQLVMs = $BisSQLVMs | sort-object -Descending ProvisionedSpaceGB
$MdnSQLVMs=[System.Collections.ArrayList]@()
$MdnSQLVMs += Get-DatastoreCluster WINDOWS2* | Get-VM -Tag 'SQL MSDN' -Server itdvmvc2.nd.gov | sort-object Name
$MdnSQLVMs += Get-DatastoreCluster WINDOWS2* | Get-VM -Tag 'SQL Enterprise Academic' -Server itdvmvc2.nd.gov | sort-object Name
$MdnSQLVMs += Get-DatastoreCluster WINDOWS2* | Get-VM -Tag 'SQL Standard' -Server itdvmvc2.nd.gov | sort-object Name
$MdnSQLVMs = $MdnSQLVMs | sort-object -Descending ProvisionedSpaceGB
+43
View File
@@ -0,0 +1,43 @@
$Report = @()
$VMs = get-vm -name itdtufin.nd.gov
$Datastores = Get-Datastore | select Name, Id
Get-VIEvent -Entity $VMs -MaxSamples ([int]::MaxValue) -ov x |
$x | where {$_ -is [VMware.Vim.VmPoweredOnEvent] -or $_ -is [VMware.Vim.VmPoweredOffEvent]} -ov y|
Group-Object -Property {$_.Vm.Name} | %{
$lastPO = $_.Group | Sort-Object -Property CreatedTime -Descending | Select -First 1
$vm = Get-VM -Name $_.Name
$row = '' | select VMName,Powerstate,OS,Host,Cluster,Datastore,NumCPU,MemMb,DiskGb,PowerOFF
$row.VMName = $vm.Name
$row.Powerstate = $vm.Powerstate
$row.OS = $vm.Guest.OSFullName
$row.Host = $vm.VMHost.name
$row.Cluster = $vm.VMHost.Parent.Name
$row.Datastore = ($Datastores | where {$_.ID -match (($vm.Datastore | Select -First 1) | Select Value).Value} | Select Name).Name
$row.NumCPU = $vm.NumCPU
$row.MemMb = $vm.MemoryMB
$row.DiskGb = ((($vm.HardDisks | Measure-Object -Property CapacityKB -Sum).Sum * 1KB / 1GB),2)
$row.PowerOFF = $lastPO.CreatedTime
$report += $row
}
$report | Sort Name | Export-Csv -Path "C:\XXXXX\Powered_Off_VMs.csv" -NoTypeInformation -UseCulture
+38
View File
@@ -0,0 +1,38 @@
$VMs = Get-VM itdprint1a.nd.gov,itdprint1b.nd.gov | where-object PowerState -eq PoweredOn
$count=0
ForEach ($VM in $VMs)
{
$count++
$Cluster = $null
$DatastoreCluster = $null
$DatastoreLargest = $null
$DatastoreDestination = $Null
$vCenter = $null
$Templ = $null
$vCenter = $VM.uid.split('@')[1].split('.')[0]
$TEMPL = Get-Datastore "*TEMPL*" | where-object Uid -like "*$vCenter*"
$Cluster = $VM | Get-Cluster
$DatastoreCluster = $VM | Get-DatastoreCluster
$DatastoreLargest = $DatastoreCluster | Get-Datastore | sort-object FreeSpaceGB -Descending | select -first 1
If($DatastoreLargest.FreeSpaceGB -gt $VM.UsedSpaceGB)
{
$DatastoreDestination = $DatastoreCluster
}
Else
{
$DatastoreDestination = $TEMPL
}
If($Count -le 8)
{
New-VM -VM $VM -Name ($VM.Name + "_backup20191021") -ResourcePool $Cluster -Datastore $DatastoreDestination -RunAsync
}
else {
New-VM -VM $VM -Name ($VM.Name + "_backup20191021") -ResourcePool $Cluster -Datastore $DatastoreDestination
start-sleep -seconds 180
$count = 0
}
}
+70
View File
@@ -0,0 +1,70 @@
$disks = Get-DatastoreCluster SQL2_A9K_General_KeepTogether | Get-Datastore | Get-vm | get-harddisk | select Parent,CapacityGB,Persistence,@{n='Datastore';e={$_.Filename.split(' ')[0]}}
$disks | where-object Datastore -notlike "*CND*" | sort-object CapacityGB -Descending
$disks | where-object Datastore -notlike "*CND*" | where-object Persistence -like "IndependentPersistent" | where-object {$_.Datastore -notlike "*171*" -or $_.Datastore -notlike "*174*" -and $_.Datastore -notlike "*175*" -and $_.Datastore -notlike "*176*" -and $_.Datastore -notlike "*177*" -and $_.Datastore -notlike "*178*" -and $_.Datastore -notlike "*185*"}
$VMSize = @()
$disks | group-object Parent | ForEach-Object {
$obj=[PSCustomObject]@{
'VM' = $_.Name;
'SizeGB' = ($_.Group | measure-object CapacityGB -sum).sum
}
$VMSize += $obj
}
#### MOVE _CND NEXT
$disks = Get-DatastoreCluster SQL2_A9K_General | Get-Datastore | Get-vm | get-harddisk | select Parent,CapacityGB,Persistence,@{n='Datastore';e={$_.Filename.split(' ')[0]}}
$disks | group-object Parent | ForEach-Object{
$_.Group | where-object Persistence -eq IndependentPersistent | sort-object CapacityGB -Descending | select -first 1
}
$disks | group-object Parent | select Name,@{n='MaxIPDiskSizeGB';e={($_.Group | Where-Object Persistence -eq IndependentPersistent | sort-object CapacityGB -Descending | select -first 1).CapacityGB}},@{n='MaxIPDiskDatastore';e={($_.Group | Where-Object Persistence -eq IndependentPersistent | sort-object CapacityGB -Descending | select -first 1).Datastore}},@{n='TotalSizeGB';e={($_.group | measure-object CapacityGB -Sum).Sum}},@{n='DatastoreCount';e={@($_.group).count }} | sort-object MaxIPDiskSizeGB -Descending | ft
$VMs = Get-DatastoreCluster SQL1_A9K_General | Get-VM
$AllDisks = $VMs | Get-HardDisk | select Parent,CapacityGB,Persistence,@{n='Datastore';e={$_.Filename.split(' ')[0]}}
$result = @()
ForEach($VM in $VMs)
{
$VMDisks = $VM | Get-HardDisk | select Parent,CapacityGB,Persistence,@{n='Datastore';e={$_.Filename.split(' ')[0]}}
If(($VMDisks | select -Unique Datastore).count -gt 1)
{
$obj=[PSCustomObject]@{
'VMName' = $VM.Name;
'SumGB' = (Get-VM $VM.Name | Get-HardDisk | measure-object CapacityGB -Sum).Sum;
}
$result += $obj
}
}
$result | sort-object SumGB -Descending
<# Manual SQL SDRS
- get amount of space required to find a home for
- find datastore with the most VMs under under 2TB
- do those VMs take up more space than desired amount?
- if yes, move VMs to other datastores
- create new object with before and after usage
- find largest VM in group, move to datastore with highest free space
- repeat until enough specified space exists
- if no, find datastore with the most free space
- create new object with before and after usage
- move the largest vm on that datastore to the datastore with the 2nd most free space
- repeat until enough specified space exists
# >
169
*Select "Change" only if changes need to go to VM admins.
*Select "Delete" to have the VM removed and permanently deleted

Some files were not shown because too many files have changed in this diff Show More