Using Powershell to get a vm's own name - powershell

The short question is; can a VM use powershell to get its own name?
I have an environment where I have 12 identical sets of VMs. Each set has one jump server, and the naming convention is ##_APP_SET#, where ## is a corresponding NAT device, and SET# tells me the set of VMs.
On this APP VM, I have created a menu that uses an account on the external vCenter to turn the VMs in the set on and off. So from within the VM, it is connecting to its parent vCenter and running an action on another VM in the set. The problem is that I have the VM names hard coded in the script. For example, if I'm on 01_APP_SET1, I have a bunch of entries for 01_MACHINENAME_SET1, and on 02_APP_SET2, I have entries for 02_MACHINENAME_SET2, etc.
I am currently managing 12 different scripts on the 12 different APP VMs. I am hoping to make the script more general where the VM calls a get-vm on itself and parses out the preceding ## and trailing SET#, but not having much luck beyond getting a list of systems called APP with get-vm APP.
I'm thinking the best way to tackle this would be to give each APP VM a hostname matching its name in vCenter, then parsing out the information that way.

Is there any sort of identifiable information that is unique to the APP VM such as a external facing IP to be able to log in to outside of the private networking for the Set?
Perhaps something like this would be helpful:
$ip = (ipconfig | Select-String "IPv4 Address" | Select-String "192.168.1").Line.Replace("IPv4 Address. . . . . . . . . . . :","")
$vm = get-vm | ?{$_.Guest.IPAddress -like $ip}

Or group the VMs with tags in VC and use Invoke-VMScript to poke around other guests as necessary.

Related

Any way to identify the Computer's OU information from local WMI or Registry

I'm looking for a way to obtain the OU information of a computer from its local WMI or Registry. I know there are ways to pull the OU information from a host using PowerShell and AD commandlets... Afraid every time we execute the commands, it will hit the domain controller and pull the information. If we run similar commands simultaneously on a large number of computers, it would spike the number of connections to Domain Controllers. We would like to avoid such cases and see if we can find a way to obtain the OU information if it's stored locally in the host.
I did find a few sample codes from other responses and they are working well, however, I feel they are retrieving the information from Domain Controller (sorry if I misunderstood). Could someone confirm if this is the only option we have to use or is there any alternative solution?
Sample Code:
([adsisearcher]"(&(name=$env:computername)(objectClass=computer))").findall().path
(or)
Import-Module ActiveDirectory -Force;
Get-ADComputer $env:computername | select -ExpandProperty DistinguishedName
Thanks,
Nana

Powershell script to Find all VMs without a security tag and group

I have powercli module installed and cannot get powernsx to work no matter what I try, so I'm limited to direct API calls to NSX.
The goal is to report on all VMs that do not have a security tag applied.
I know i can see all VMs with Get-VM, and I can get all security tags calling https://10.x.x.x/api/2.0/services/securitytags/tag
That security tag call will only return the number of VMs it's applied to, and not the names. I need the names so I can compare to the output from Get-VM.
Does anyone know how to see the names of all the VMs that have security tags from NSX? The issue is sys admins spin up new servers and do not tag them. Need to see which ones are untagged.
See if this command helps you find what you are looking for, (reference)
Get-VM | Get-NsxSecuritytagassignment | select-object #{Name="SecurityTag"; expression = {$_.securitytag.name}}, VirtualMachine

How to get an environment variable in a Powershell script when it is deployed by SCCM?

I've made a script to automatically change and/or create the default Outlook signature of all the employees in my company.
Technically, it gets the environment variable username where the script is deployed, access to the staff database to get some information regarding this user, then create the 3 different files for the signature by replacing values inside linked docx templates. Quite easy and logical.
After different tests, it is working correctly when you launch the script directly on a computer, either by using Powershell ISE, directly by the CMD or in Visual Studio. But when we tried to deploy it, like it will be, by using SCCM, it can't get any environment variable.
Do any of you have an idea about how to get environment variables in a script when it is deployed by SCCM ?
Here is what I've already tried :
$Name = [Environment]::UserName
$EnvVarUserName = Get-Item Env:\USERNAME
Even stuff like this :
$proc = gwmi win32_process -Filter "Name = 'explorer.exe'"
$report = #()
ForEach ($p in $proc)
{
$temp = "" | Select User
$temp.user = ($p.GetOwner()).User
$report += $temp
}
Thanks in advance and have a nice day y'all !
[EDIT]:
I've found a way of doing this, not the best one, but it works. I get the name of the machine, check the DB where when a laptop is connected to our network it stores the user id and the machine, then get the info in the staff DB.
I will still check for Matt's idea which is pretty interesting and, in a way, more accurate.
Thank you all !
How are you calling the environmental variable? $Env:computernamehas worked for me in scripts pushed out via SCCM before.
Why don't you enumerate the "%SystemDrive%\Users" folder, exclude certain built-in accounts, and handle them all in one batch?
To use the UserName environment variable the script would have to run as the logged-in user, which also implies that all of your users have at least read access to your staff database, which, at least in our environment, would be a big no-no.

Distinguish Windows services with the same ProcessName

I am adjusting a monitoring system which checks if a service is running or not. It does that by checking the process name and it's memory consumption. Once it drops below 1 MB an alert is triggered. Also I use the memory usage value to display it in a graph. So checking and notifying is not the only purpose.
Currently I have 5 Windows services using the same ProcessName and I don't know how to make my script distinguish them. The ServiceName for each service is of course different and the path to the executable as well.
When I run get-process I see them all, but I don't see an option here distinguish them. Using get-service doesn't help much either, because it returns name, displayed name and status. Somehow I would love to combine the entries to see the memory usage by service name, not by process name.
You say that the path to executable is different - this way you can distinguish the processes by querying path property. Should they be equal, you can also query StartInfo object of a process to get Arguments property to discern from one another. But the best way to get correct process instances will be to query WMI objects of type Win32_Service to filter your services out, this way you can find if one of them is stopped as well, and then get the process by passing the ProcessId property of the WMI service object. For running services, the PID will be valid. An example (which only filters by service name):
gwmi win32_service | ? {$_.name -eq "wsearch"} | % {get-process -id $_.processid}
Note that there is a possibility that one process will handle more than a single service, this is called "Shared service process" and is visible in Get-Service output as ServiceType property of the returned service, the value Win32SharedProcess (0x20) indicated the underlying PID can be shared, although it's not always the case. The most known shared service process is svchost.exe which also has a sort of a namespace to determine which process should host a certain service, passed to it as a command line parameter.

Creating Hyper-V VMs with unique names using Powershell

I'm trying to make some sort of script that creates a new VM, only need it to be told to create a unique VM name (with some sort of logic, if possible, to check for existing names and using something different automatically or just telling me to use something else) . I understand a new VM is made using a unique GUID by default so there are no system conflicts, but I further need my script to go in and perform commands on the VM, such as starting the VMs, copying files onto it, etc. without a unique name I'm not sure how the script can automatically give commands to the right one.
For example, I have:
New-VM TestServer1 -AsJob -Generation 2 -MemoryStartupBytes 8192MB -NoVHD -SwitchName VSwitch-1
but if a VM named 'TestServer1' already exists, and I were to have my script automatically run:
Start-VM TestServer1
both VMs would turn on...
Edit:
Also, I know one can export the results of creating a new VM using 'Out-File' but I don't know what cleanest way to format the output to be read back later.