Jump to content

AnEngelsen

Members
  • Posts

    62
  • Joined

  • Last visited

  • Days Won

    9

Posts posted by AnEngelsen

  1. @Sean, I think you'll find that when you run Gwmi win32_groupuser (as the SYSTEM user) on a system that is AD bound, the resulting output will show members of the Administrators AD Group, as well as the local Administrators group. I only care about who is a member of the local Administrators group.

    That's why I'm defaulting to the net localgroup administrators command.

  2. I simplified the Windows script:

     $administrators = net localgroup administrators |
        Select-String -Pattern '^-+\s*(.+)' -Context 1, 100 |
        ForEach-Object { $_.Context.PostContext } |
        Where-Object { $_ -notmatch '^-+$|^The command completed successfully\.|^Alias name|^Comment|^Members|^Administrator|^Domain\s*Admins\s*|^Enterprise\s*Admins\s*' } |
        ForEach-Object { $_ -replace '^SHIRTFACTORY\\' }
    
    $usernamesString = "," + ($administrators -join ',')
    $usernamesString

    Some (but not all) of my Windows desktop clients reference "Domain Admins" within the Custom Field. When I run the script as Administrator within PowerShell ISE (x68) I do not get any references to "Domain Admins". Why?

  3. @Sean I'm noticing that the "Gwmi win32_groupuser" command appears to be reporting on all AD Groups (if the desktop client is bound to Active Directory). I only need to know who's a member of the local Administrators group.

    As such, I modified my script as follows:

    # Get the list of administrators using the net localgroup command and extract usernames
    # The "context" attribute is used to retrieve 100 lines after the line of dashes, to (fingers crossed) capture all potential usernames.
    $administrators = net localgroup administrators | Select-String -Pattern '^-+\s*(.+)' -Context 1, 100 | ForEach-Object { $_.Context.PostContext }
    
    # Remove empty lines and lines containing non-username information
    $administrators = $administrators -match '\S' -replace '^\s*(?:The command completed successfully\.|Alias name|Comment|Members|-+)'
    
    # Remove known users from the array
    $administrators = $administrators | Where-Object { $_ -notin @('Administrator', 'Domain Admin') }
    
    # Join the usernames array into a single string separated by commas
    $usernamesString = $administrators -join ','
    
    # Output the usernames string
    Write-Host ",$usernamesString"

     

  4. Great post, Sean! I appreciate you taking into consideration ease of searchability/filtering.

    These 1-2 lines of code will go a long way towards allowing my team to audit who has local admin permissions. (FileWave is allowing us to keep that list of people very, very short.) 😀

  5. This is an alternative script that does the same thing within a Powershell 32-bit environment: 

    # Function to get the substring after the backslash using Microsoft.VisualBasic.Strings.Mid
    function Get-SubstringAfterBackslash($str) {
        Add-Type -AssemblyName Microsoft.VisualBasic
        [Microsoft.VisualBasic.Strings]::Mid($str, $str.IndexOf("\") + 2)
    }
    
    # Get the list of administrators using the net localgroup command
    $administrators = net localgroup administrators | Where-Object {$_ -and $_ -notmatch "^The command completed successfully|^Alias name|^Comment|^Members|^-"} | ForEach-Object { Get-SubstringAfterBackslash $_ }
    
    # Join the usernames array into a single string separated by spaces
    $usernamesString = $administrators -join ' '
    Write-Output $usernamesString

     

    Here is the script that I'm using with macOS clients. It requires (1) launch argument. (The group name.)

    I have the launch argument set to: admin

    #!/bin/bash
    
    # members -- list all members of a group
    #
    # SYNOPSIS
    #   members groupname
    #
    # Source: http://superuser.com/questions/279891/list-all-members-of-a-group-mac-os-x
    # Expected to work on Mac OS 10.5 and newer, tested on 10.6 and 10.7.
    # It could be rewritten to work on 10.4 by using "dseditgroup -o checkmember"
    # instead of "dsmemberutil checkmembership".
    # By using dseditgroup, the script could also be extended to handle
    # other Directory Service nodes than the default local node.
    #
    
    the_group="$1"
    # Input check and usage
      if [[ $# != 1 || $1 == -* || $1 =~ [[:space:]] ]]; then
        echo "Syntax: ${0##*/} GroupName_GoesHere" >&2
        exit 64
      elif (dsmemberutil checkmembership -U root -G "$the_group" 2>&1 \
        | grep "group .* cannot be found") >&2; then
        exit 1
      fi
    
    # Check every user
    exec dscl . -list /Users \
      | while read each_username
      do
        printf "$each_username "
        dsmemberutil checkmembership -U "$each_username" -G "$the_group"
      done \
        | grep "is a member" | cut -d " " -f 1
    
    # eof

     

  6. I have a PowerShell script that lists members of the (local) Administrators user group. The script produces 1-line of output (when run locally) but results in NULL output when assigned to a custom field. What am I doing wrong?

    $listOfAdministrators = $(Get-LocalGroupMember -Group "Administrators").name
    $usernames = @()
    
    foreach ($name in $listOfAdministrators) {
        $position = $name.IndexOf("\")
        $usernames += $name.Substring($position + 1)
    }
    
    # Join the usernames array into a single string separated by spaces
    $usernamesString = $usernames -join ' '
    
    Write-Output $usernamesString

     

  7. Here is the FWClient output from (2) different desktop devices:

    Wait for executable to finish: Infinite
    The installation never completes. Instead, the desktop continues to try to talk to the FileWave Server. But the TLS/SSL Connection is getting closed.

    2023-11-10 9:11:30.323|main|INFO|CLIENT|Done processing Container Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224
    2023-11-10 9:11:30.930|main|INFO|CLIENT|about to downloadAllFileset files for Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224
    2023-11-10 9:11:31.564|main|INFO|CLIENT|Downloading Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224
    2023-11-10 9:11:33.779|main|INFO|CLIENT|finished downloadFileset files for Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224
    2023-11-10 9:11:33.781|main|INFO|CLIENT|Create all folders of fileset ID Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224, version 5
    2023-11-10 9:11:33.782|main|INFO|CLIENT|Activate all files of Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224, version 5
    2023-11-10 9:11:34.124|main|INFO|CLIENT|Done activating all 2 files of Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224, version 5
    2023-11-10 9:12:32.172||INFO|CLIENT|[FW::client::ClientSubscriptionController::onClientMsg] received message of type connect_update_controller, topic is client.3090993.connect_update_controller, {"hostName": "lifeisgood.filewave.net", "port": 20441}.
    2023-11-10 9:12:44.508|StatusServer|INFO|CLIENT|StatusConnectionHandler socket error: The TLS/SSL connection has been closed
    2023-11-10 9:17:56.329||INFO|CLIENT|[FW::client::ClientSubscriptionController::onClientMsg] received message of type connect_update_controller, topic is client.3090993.connect_update_controller, {"hostName": "lifeisgood.filewave.net", "port": 20441}.
    2023-11-10 9:17:58.465|StatusServer|INFO|CLIENT|StatusConnectionHandler socket error: The TLS/SSL connection has been closed
    2023-11-10 9:22:09.117||INFO|CLIENT|[FW::client::ClientSubscriptionController::onClientMsg] received message of type connect_update_controller, topic is client.3090993.connect_update_controller, {"hostName": "lifeisgood.filewave.net", "port": 20441}.
    2023-11-10 9:22:15.325|StatusServer|INFO|CLIENT|StatusConnectionHandler socket error: The TLS/SSL connection has been closed
    

     

    Wait for executable to finish: 5 min
    The fwcld output implies that the install completed successfully (within seconds).
    However, the Client Monitor tells a different story. The FileWaveWinClient hangs on "Executing Activation Scripts..." for 5minutes. (After the 5 minutes elapse) the client starts checking for new model updates.

    2023-11-10 11:58:13.297|main|INFO|CLIENT|Fileset Container ID 2978224, revision ID 2978224 has version 8. It contains 3 files and 4 folders
    2023-11-10 11:58:13.297|main|INFO|CLIENT|Done processing Container Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224
    2023-11-10 11:58:13.864|main|INFO|CLIENT|about to downloadAllFileset files for Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224
    2023-11-10 11:58:14.009|main|INFO|CLIENT|Skipped download of 3 files (100 percent of data) for Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224 because they match existing copies on this machine.
    2023-11-10 11:58:14.183|main|INFO|CLIENT|Downloading Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224
    2023-11-10 11:58:14.442|main|INFO|CLIENT|finished downloadFileset files for Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224
    2023-11-10 11:58:14.443|main|INFO|CLIENT|Create all folders of fileset ID Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224, version 8
    2023-11-10 11:58:14.444|main|INFO|CLIENT|Activate all files of Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224, version 8
    2023-11-10 11:58:14.714|main|INFO|CLIENT|Failed to set file for reboot C:\ProgramData\FileWave\FWClient\FW3038680
    2023-11-10 11:58:14.717|main|INFO|CLIENT|Done activating all 3 files of Fileset EXE - Install Anydesk CM, ID 2978224, revision v8.0.6, ID 2978224, version 8
    2023-11-10 11:58:16.787|main|INFO|CLIENT|Executed C:/ProgramData/FileWave/fwEXE/AnyDesk/Install_AnyDesk.bat Return Code: 0
    2023-11-10 11:58:17.221|main|INFO|CLIENT|Installation(s) Completed.
    2023-11-10 11:58:17.223|main|INFO|CLIENT|[FW::Catalog::processManifest] Number of restrictions: 0 (ESF3090865M)
    2023-11-10 11:58:17.224|main|INFO|CLIENT|[FW::Catalog::processManifest] Number of restrictions: 0 (ESF466575M)
    2023-11-10 11:58:17.224|main|INFO|CLIENT|[FW::Catalog::processManifest] Number of filesets: 1 (ESF2389200M)
    2023-11-10 11:58:17.224|main|INFO|CLIENT|[FW::Catalog::processManifest] Number of restrictions: 0 (ESF2389200M)
    2023-11-10 11:58:25.247|main|INFO|CLIENT|non threaded scan for InventoryScanner started
    2023-11-10 11:58:25.248|main|INFO|CLIENT|finished scan for InventoryScanner
    2023-11-10 11:58:25.249|main|INFO|CLIENT|Windows Software Updates Available 7
  8. I have a .bat script that allows me to install AnyDesk. The script works great (2 sec runtime, exits with a status of 0) when it is run locally as the SYSTEM user. However, when I run the .bat Activation Script via FileWave, the FileWave Client gets (indefinitely) stuck on `Executing Activation Scripts...`.

    As a temporary workaround I have modified the fileset's executable settings. (Wait for executable to finish has been changed from Infinite to 5 minutes.)

    Screenshot2023-11-10at11_42_22AM.png.9245deda5ae776cc59178774c2695827.png

    Has anyone else run into a similar problem while trying to deploy software using a .bat script?

     
  9. Great! This fileset should prevent folks from upgrading via the MacOS App store.

    And...the MDM Restrictions profile can be used to prevent users from upgrading via the System Settings app.Screenshot2023-09-29at2_27_36PM.png.16c6eb3327f492c06d977eaf54b4fdd5.png

     

    Word of warning, before applying any changes to an existing Restrictions profile, ensure you review and modify any unchecked settings. (New options might have been added to since the last time the profile was modified.)

  10. Based on what I'm seeing in the API docs (https://FileWaveServer_URLGoesHere/api/doc/), the FileWave API requires you to provide the ClientID or DeviceID to perform a device lookup. (You cannot pass the serial number as the unique identifier.)

    That said, you might be able to build an inventory query that contains that device serial number and the piece of information you want to capture.

    Then you would use the API to reference the inventory query (and the resulting inventory data): https://fwkb.atlassian.net/wiki/spaces/KB/pages/4328035/RESTful+API#RESTfulAPI-Commands

     

    • Like 1
  11. @Jeffreythis PS1 script works for me:

    #####################Written by Darcey S @ FileWave 3/30/2015#########################
    
    #####Please update the below variables for your environment###############################
    
    $user = "shirtfactory.local\adbind"
    
    #I'm passing the password using an Enviornmental Variable.
    $password = "$Env:PW"
    
    $domain = "orgName.local"
    
    # $ou = "ou=organizationalUnit,ou=NameGoesHere,dc=shirtfactory,dc=local"
    
    ########DON'T MODIFY BELOW THIS LINE##############################################
    
    
    
    $pass = ConvertTo-SecureString $password -AsPlainText -Force
    
    $DomainCred = New-Object System.Management.Automation.PSCredential $user, $pass
    
    Add-Computer -DomainName $domain -Credential $DomainCred # -OUPath ($ou)
    
    
    
    Remove-Item $MyINvocation.InvocationName
    
    Restart-Computer -Force

     

     

    • Like 1
  12. If anyone wants to launch the FileWave Kiosk from the Start Menu (Windows), or the Applications folder (macOS) here are (2) filesets that allow you to do just that!

    Windows: ShowFileWaveKiosk-Windows.zip

    MacOS: https://cdn.discordapp.com/attachments/1018883735640350852/1095421174630055946/ShowFileWaveKiosk-macOS.zip

    I crafted these filesets because Windows doesn't have a scripted solution that allows you to "Always Show" an icon in the Notification Area.
    As for macOS users, if you increase the display size (or have too many toolbar icons), the FileWave Kiosk icon will become inaccessible (not visible).

    This approach ensures that EVERYONE has easy-access to the FileWave Kiosk.

     

    • Thanks 2
  13. @Sean, is there a reason why you choose to use both a launch agent and a launch daemon? (The previous fileset only used a launch agent.)

    Also, the Watch Paths key got stripped from the new/revised .plist. (Was that intentional?)871478454_Screenshot2023-01-25at8_57_24PM.png.d123cbb0eb8c3e0952efedb1dc347179.png

     

    Finally, I also wanted to highlight the changes to the kill_macos_major_update.sh file. (In case anyone was wondering "what changed".)

    1681561572_Screenshot2023-01-25at9_07_00PM.png.28e099b23a8364520d0a34b4935c7430.png

  14. This fileset allows you to block the initial install attempt. However, if the user revisits System Preferences -> Software Update -> Update, they are able to install Ventura.

    They are not presented with another notification from Pashua.app.

  15. Here are instructions that explain the full process:

    I'm re-uploading the screenshots. (They should now be significantly less blurry.)

    Overview:

    Custom fields can be manually associated to FileWave desktop clients. You can also associate a custom field to all desktop devices. However, If you want the ability to automatically enable/disable a custom field association from a specific group of clients, you will need to use the FileWave API.

    Here's how:

    1. Log into FileWave Admin. Create a new FileWave Administrator account. Call this user something along the lines of API_helper.
      1. Assistants (menu) -> Manage Administrators
    2. Go to the Application Tokens tab. Copy the base64 token to a secure note. (You'll need it later on.)Step02.png.9b959c1f1ebcecf553f1e9850aede9bc.png

       
    3. Create (or select) a custom field. Copy the Internal Name to the same secure note. (You'll need it later on.)
      1. Custom fields can be found in: Assistants (menu) -> Custom Fields -> Edit Custom FieldsStep03.png.b0814c8cc76ae94f4934b974291cf8a4.png

         
    4. Import the .fileset file that I have attached to this post. FilesetExport-SetCustomFieldAssociation.zip
      1. Importing a fileset: Filesets (in the sidebar) -> New Desktop Fileset (top of window) -> ImportStep04.png.e6464a44ff146f80af0f915abdc1ea6b.png

         
    5. Double-click the (recently-imported) fileset. Locate, then double-click, on the .ps1 or .sh script.Step05.png.0193e42c4cfe80e5ca12dbbc6ce60abb.png

       
    6. Select the Executable (tab) -> Enviornment Variables (tab)
    7. Replace the value of the CF_Name variable with the Internal Name. (Copied during step #3)
    8. Replace the value of the apitoken variable with the base64 token. (Copied during step #2)
    9. Click Apply.
    10. Associate the fileset to a "test device".
      1. Right-click the test client. Choose Edit custom field values. Verify that the client does not currently possess the custom field.
    11. Update the model.
    12. Right-click the test device. Choose Edit custom field values.
    13. Verify that the test client now has the custom field associated to it. (Delete the client <--> fileset association. Created in step #10)
    14. Create a smart client group. Associate the fileset (from step #4) to the smart client group.
    15. Update the model.
    16. Done! 🥳

    If you want to automatically disassociate a custom field (when a client leaves the smart group), you could repurpose the same script (applied as a pre-uninstall script). Just change the CF_Value to false.

    • Thanks 1
  16. @Larry Benshoof very nice!

    This script will tell you the max battery capacity:

    All credit goes to FileWave! (But I can't remember who.) 😛

    MacOS (Shell)

    #!/bin/bash
    # -2 => No battery present
    # Any non-negative number => max % of original capacity battery can charge to
    
    temp=`ioreg -brc AppleSmartBattery`
    if [ -z "$temp" ]; then
    	echo "-2"
    else
    	MaxCapacity=`ioreg -brc AppleSmartBattery | grep \"MaxCapacity\" | cut -d "=" -f 2 | sed 's/ //g'`
    	DesignCapacity=`ioreg -brc AppleSmartBattery | grep '"DesignCapacity" =' | cut -d "=" -f 2 | sed 's/ //g'`
    	MaxChargeCapacity=`echo "scale=2 ; $MaxCapacity / $DesignCapacity" | bc`
    	echo "($MaxChargeCapacity * 100) / 1" | bc
    fi
    
    exit 0

    Windows (PowerShell)

    # Possible values
    # -1 => Battery info unavailable
    # -2 => No battery present
    # Any non-negative number => max % of original capacity battery can charge to
     
    if (Get-WmiObject -Class "MSBatteryClass" -Namespace "ROOT\WMI"){
        $DesignCapacity=Get-WmiObject -Class "MSBatteryClass" -Namespace "ROOT\WMI" | select -ExpandProperty DesignedCapacity
    } else {
        Write-output "-2" #No battery present
    break
    }
    
    $FullChargedCapacity=Get-WmiObject -Class "BatteryFullChargedCapacity" -Namespace "ROOT\WMI" | select -ExpandProperty FullChargedCapacity
     
    if ($FullChargedCapacity -eq 0 -or $DesignCapacity -eq 0){
        Write-output "-1" #Battery info unavailable
        break
    } else
    {
        $BatteryCapacity = ($FullChargedCapacity / $DesignCapacity) * 100
        if ($BatteryCapacity -gt 100) {$BatteryCapacity = 100}
     
        $BatteryCapacity = [decimal]::round($BatteryCapacity)
        $BatteryCapacity
    }
    
    exit 0 

     

    • Like 1
  17. @Larry Benshoof I'm displaying the uptime in a "pretty" format. Does your Uptime custom field display the uptime in seconds? Otherwise, I'm not sure how you would be able to effectively create a smart client group (that contains clients w. an uptime that is higher than 60 days).

×
×
  • Create New...