Restricted software for Parallels Desktop

Bernard_Huang
Contributor III

Hi all,

Due to 'reasons' such not able to check VM's being hosted within Parallels Desktop, my company has decided to restrict Parallels Desktop from running within macOS for everyone.

I am currently setting up a Restricted Software for Parallels.
- I have setup various Process Name such as Parallels, "Parallels Desktop", Parallels D*, etc, with and without " quotes.
- I have turned off or on Restrict exact process name
- I have turned on Kill Process

But no matter the combinations I tried for Process Name or Restrict Exact Process Name, I either get:
- When Restrict exact process name = on, the restriction does not work at all. I can still start Parallels Desktop, no matter what name I put in.
- When Restrict exact process name = off, the restriction works too well. Even when I have Parallels not running, it kill message pops up every 15 minutes, asking the user to stop using Parallels.

Does anyone else know how to restrict Parallels Desktop properly? Just only when it is attempting to start?

I have checked Activity Monitor in real time. Parallels Desktop process is exactly how it is spelled, with the capitals. When Parallels is off, I did a search, there really is no other process similar to Parallels or Desktop or Para or Desk, etc.

Thanks in advance.

1 ACCEPTED SOLUTION

tlarkin
Honored Contributor

You can totally get the VM host OS in Parallels. I have not published this on my GitHub yet but I can do it here for now

#!/usr/bin/python

"""
this is a script to detect what VMs are on a sytsem and escrow what OS they are
You can run this daily or in another workflow
It will use Spotlgith to find files with the .pvm extension to locate where the files are on the file system
then parse the PvInfo file for Parallels VMs
"""

# import modules
import xml.etree.ElementTree as et
from Foundation import NSMetadataQuery, NSPredicate, NSRunLoop, NSDate


# start functions


def get_vms():
    """use spotlight to find parallels VM files"""
    file_list = []
    query = NSMetadataQuery.alloc().init()
    query.setPredicate_(NSPredicate.predicateWithFormat_("(kMDItemContentType == 'com.parallels.vm.vmpackage')"))
    query.setSearchScopes_(['/Applications', '/Users'])
    query.startQuery()
    start_time = 0
    max_time = 20
    while query.isGathering() and start_time <= max_time:
        start_time += 0.3
        NSRunLoop.currentRunLoop(
        ).runUntilDate_(NSDate.dateWithTimeIntervalSinceNow_(0.3))
    query.stopQuery()
    # get the results of the file names, and find their file path via spotlight attribute
    for item in query.results():
        pathname = item.valueForAttribute_('kMDItemPath')
        if pathname:
            file_list.append(pathname)
    return file_list


def get_vm_os(vm_list):
    """feed this function a list of results from Spotlight to parse what VM is running what OS"""
    os_list = []
    for vm in vm_list:
        path = str(vm + '/VmInfo.pvi')
        tree = et.ElementTree(file=path)
        for element in tree.iter(tag='RealOsType'):
            vm_os = str(element.text)
            os_list.append(vm_os)
    return os_list


def main():
    """main to rule them all"""
    final_vm_list = []
    ea_list = []
    files = get_vms()
    results = get_vm_os(files)
    for result in results:
        if 'Mac' in result:
            final_vm_list.append('macOS')
        if 'Linux' in result:
            final_vm_list.append('Linux')
        if 'Windows' in result:
            final_vm_list.append('Windows')
    for item in final_vm_list:
        if item not in ea_list:
            ea_list.append(item)
    print('<result>%s</result>' % ea_list)


if __name__=='__main__':
    main()

here goes my example output as an EA:

/usr/bin/python2.7 /Users/tlarkin/IdeaProjects/tlarkin/get_VM_OS.py
<result>['Windows', 'macOS', 'Linux']</result>

I could use some cleaning up maybe but you can 100% detect and my code uses Spotlight so it doesn't matter where the user puts the VM, I will find it!

View solution in original post

5 REPLIES 5

Bernard_Huang
Contributor III

I think I got it :)

From Terminal, I did a ps -ax to list out ALL the process.
This list is more comprehensive than shown in Activity Monitor.

I found the Parallels Desktop process is acutally named prl_client_app

Therefore, within my Restricted Software, I now have
Process Name = prl_client_app
Restrict exact process name = Yes

I think I got it, because when I try and start Parallels, it really does kill the process.
And every 15 minutes or so, there is no message pop-up.

tlarkin
Honored Contributor

You can totally get the VM host OS in Parallels. I have not published this on my GitHub yet but I can do it here for now

#!/usr/bin/python

"""
this is a script to detect what VMs are on a sytsem and escrow what OS they are
You can run this daily or in another workflow
It will use Spotlgith to find files with the .pvm extension to locate where the files are on the file system
then parse the PvInfo file for Parallels VMs
"""

# import modules
import xml.etree.ElementTree as et
from Foundation import NSMetadataQuery, NSPredicate, NSRunLoop, NSDate


# start functions


def get_vms():
    """use spotlight to find parallels VM files"""
    file_list = []
    query = NSMetadataQuery.alloc().init()
    query.setPredicate_(NSPredicate.predicateWithFormat_("(kMDItemContentType == 'com.parallels.vm.vmpackage')"))
    query.setSearchScopes_(['/Applications', '/Users'])
    query.startQuery()
    start_time = 0
    max_time = 20
    while query.isGathering() and start_time <= max_time:
        start_time += 0.3
        NSRunLoop.currentRunLoop(
        ).runUntilDate_(NSDate.dateWithTimeIntervalSinceNow_(0.3))
    query.stopQuery()
    # get the results of the file names, and find their file path via spotlight attribute
    for item in query.results():
        pathname = item.valueForAttribute_('kMDItemPath')
        if pathname:
            file_list.append(pathname)
    return file_list


def get_vm_os(vm_list):
    """feed this function a list of results from Spotlight to parse what VM is running what OS"""
    os_list = []
    for vm in vm_list:
        path = str(vm + '/VmInfo.pvi')
        tree = et.ElementTree(file=path)
        for element in tree.iter(tag='RealOsType'):
            vm_os = str(element.text)
            os_list.append(vm_os)
    return os_list


def main():
    """main to rule them all"""
    final_vm_list = []
    ea_list = []
    files = get_vms()
    results = get_vm_os(files)
    for result in results:
        if 'Mac' in result:
            final_vm_list.append('macOS')
        if 'Linux' in result:
            final_vm_list.append('Linux')
        if 'Windows' in result:
            final_vm_list.append('Windows')
    for item in final_vm_list:
        if item not in ea_list:
            ea_list.append(item)
    print('<result>%s</result>' % ea_list)


if __name__=='__main__':
    main()

here goes my example output as an EA:

/usr/bin/python2.7 /Users/tlarkin/IdeaProjects/tlarkin/get_VM_OS.py
<result>['Windows', 'macOS', 'Linux']</result>

I could use some cleaning up maybe but you can 100% detect and my code uses Spotlight so it doesn't matter where the user puts the VM, I will find it!

Bernard_Huang
Contributor III

Wow Wow Wow!
Thanks for this, @tlarkin

I shall test this in the coming days.

tlarkin
Honored Contributor

@Bernard.Huang no problem homie! You should check out the #parallels channel on Mac Admin Slack, that is where I first wrote it and posted it at. I will eventually toss it up on my github once I clean it up a tad bit and maybe add a bit better logic to it

jimmy-swings
Contributor II

I use a smart group - based on the criteria Boot ROM - to determine whether a device is physical, or virtual. Membership of the group triggers activities to mark the device as not compliant and removed from service.