• Recent
    • Unsolved
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Register
    • Login
    1. Home
    2. HorizonG
    3. Topics
    H
    • Profile
    • Following 0
    • Followers 0
    • Topics 7
    • Posts 21
    • Best 0
    • Controversial 0
    • Groups 0

    Topics created by HorizonG

    • H

      Unsolved FOG Groups & Memberships

      FOG Problems
      • • • HorizonG
      3
      0
      Votes
      3
      Posts
      101
      Views

      H

      @HorizonG
      Solution :
      I deleted all my groups and renamed them.
      I think there’s still a bug in the DATABASE

    • H

      Customs Fields / Variables

      Feature Request
      • • • HorizonG
      1
      0
      Votes
      1
      Posts
      117
      Views

      No one has replied

    • H

      Unsolved Fog client issue version 0.13.0

      FOG Problems
      • • • HorizonG
      11
      0
      Votes
      11
      Posts
      239
      Views

      H

      @Tom-Elliott

      You’re right, I created a storage group without making the storage node.

      Here’s what I did:

      Storage Management => New Storage Group => Storage_Group Snapin => New Snapin => Powershel script => Member of Storage_Group

      The second part was to use the

      $ALL_Snapins = Get-FogObject -type object -CoreObject snapin $ALL_Snapins.data $All_Snapins_Target = ($ALL_Snapin.snapins | where {$_.storagegroupname -like "Storage_Group"}).name

      foreach ($ALL_Snapin in $ALL_Snapins)
      {
      Start-FogSnapin -hostID $FOG_HostID -snapinname ($ALL_Snapin.snapins | where {$_.storagegroupname -like “Storage_Group”}).name
      }

    • H

      Postdownload scripts and API

      General
      • • • HorizonG
      5
      0
      Votes
      5
      Posts
      344
      Views

      H

      @HorizonG

      I’m making an update to my script.

      If the computer belongs to several groups at the same time, this can cause problems.

      I now return all the groups, then the script selects only the group starting with GROUP_AUTOMATE_ …

      7679ccb4-dc09-4d19-9a3f-49b8039eeaf2-image.png

      This will copy only this folder to the local directory of the client machine : clientfolderpath=“/ntfs/FOG/Sites/$SITE_GROUP”
      136a0ede-7eec-46bc-a1bc-04560b236750-image.png

      Le script

      #!/bin/bash #Variables FOG_HOSTNAME=$hostname FOG_API_TOKEN="deleted for privacy reasons" FOG_USER_TOKEN="deleted for privacy reasons" FOG_SERVER="deleted for privacy reasons" # Adresse IP ou nom d'hôte de votre serveur FOG echo "Serveur FOG: $FOG_SERVER" # Fonction pour appeler l'API FOG function invoke_fog_api() { local fog_api_token="$1" local fog_user_token="$2" local fog_server="$3" local uri_path="$4" local method="${5:-GET}" local json_data="$6" local base_uri="http://$fog_server/fog" local uri="$base_uri/$uri_path" # Construct headers local headers=( -H "fog-api-token: $fog_api_token" -H "fog-user-token: $fog_user_token" -H "Content-Type: application/json" ) # Make API call and store response in a variable if [ "$method" == "GET" ]; then response=$(curl -s -X GET "$uri" "${headers[@]}") else response=$(curl -s -X "$method" "$uri" "${headers[@]}" -d "$json_data") fi echo "$response" } # Fonction pour obtenir les détails de l'hôte function get_fog_host() { local fog_api_token="$1" local fog_user_token="$2" local fog_server="$3" local fog_hostname="$4" response=$(invoke_fog_api "$fog_api_token" "$fog_user_token" "$fog_server" "host?name=$fog_hostname") # Vérifiez si la réponse est vide if [ -z "$response" ]; then echo "Erreur: La réponse de l'API pour l'hôte est vide." return 1 fi # Vérifiez la validité du JSON if ! echo "$response" | jq . > /dev/null 2>&1; then echo "Erreur: La réponse de l'API pour l'hôte n'est pas un JSON valide." echo "Réponse brute de l'API: $response" return 1 fi # Extraire les détails de l'hôte local host_info host_info=$(echo "$response" | jq --arg hostname "$fog_hostname" '.hosts[] | select(.name == $hostname)') if [ -z "$host_info" ]; then echo "Erreur: Aucun détail trouvé pour l'hôte $fog_hostname." return 1 fi echo "$host_info" } # Fonction pour obtenir les groupes associés à un hôte function get_fog_groups_for_host() { local fog_api_token="$1" local fog_user_token="$2" local fog_server="$3" local host_id="$4" # Récupérer les associations de groupes local response response=$(invoke_fog_api "$fog_api_token" "$fog_user_token" "$fog_server" "groupassociation") # Vérifiez la validité du JSON if ! echo "$response" | jq . >/dev/null 2>&1; then echo "Erreur: La réponse de l'API pour les associations de groupes n'est pas un JSON valide." echo "Réponse brute de l'API: $response" return 1 fi # Extraire les IDs des groupes associés à l'hôte local group_ids group_ids=$(echo "$response" | jq -r --arg host_id "$host_id" '.groupassociations[] | select(.hostID == ($host_id | tonumber)) | .groupID') # Récupérer les détails des groupes response=$(invoke_fog_api "$fog_api_token" "$fog_user_token" "$fog_server" "group") # Vérifiez la validité du JSON if ! echo "$response" | jq . >/dev/null 2>&1; then echo "Erreur: La réponse de l'API pour les groupes n'est pas un JSON valide." echo "Réponse brute de l'API: $response" return 1 fi # Afficher les détails des groupes associés dans un format simple local group_ids_array group_ids_array=$(echo "$group_ids" | jq -R -s -c 'split("\n") | map(select(length > 0) | tonumber)') echo "$response" | jq -r --argjson group_ids "$group_ids_array" \ '.groups[] | select(.id as $id | $group_ids | index($id)) | "\(.id) \(.name)"' } # Fonction pour traiter et afficher les groupes dont le nom commence par GROUP_AUTOMATE_ function process_fog_groups() { local group_data="$1" echo "Groupes associés à l'hôte (commençant par GROUP_AUTOMATE_) :" # Initialiser les index local group_index=1 # Extraire les groupes et définir les variables d'environnement while IFS= read -r line; do id=$(echo "$line" | awk '{print $1}') name=$(echo "$line" | awk '{$1=""; print $0}' | sed 's/^ *//') # Remove leading spaces from the name if [[ "$name" == GROUP_AUTOMATE_* ]]; then # Définir les variables d'environnement pour le nom et l'ID du groupe export FOG_GROUP_NAME_$group_index="$name" export FOG_GROUP_ID_$group_index="$id" # Afficher le groupe echo "GROUP NAME = $name" echo "GROUP ID = $id" export FOG_GROUP_NAME_AUTOMATE=$name export FOG_GROUP_NAME_ID=$id # Incrémenter l'index pour le prochain groupe group_index=$((group_index + 1)) fi done <<< "$group_data" } # Fonction principale pour la simulation function GetInfo_host() { local fog_api_token="$FOG_API_TOKEN" local fog_user_token="$FOG_USER_TOKEN" local fog_server="$FOG_SERVER" local fog_hostname="$FOG_HOSTNAME" # Obtenez les détails de l'hôte local local_host local_host=$(get_fog_host "$fog_api_token" "$fog_user_token" "$fog_server" "$fog_hostname") # Vérifiez si local_host est vide if [ -z "$local_host" ]; then echo "Erreur: Aucune information sur l'hôte trouvée." return 1 fi # Obtenez l'ID de l'hôte local host_id host_id=$(echo "$local_host" | jq -r '.id') if [ -z "$host_id" ]; then echo "Erreur: Impossible d'extraire l'ID de l'hôte." return 1 fi # Obtenez les groupes associés à l'hôte local host_groups host_groups=$(get_fog_groups_for_host "$fog_api_token" "$fog_user_token" "$fog_server" "$host_id") # Vérifiez si host_groups est vide if [ -z "$host_groups" ]; then echo "Erreur: Aucune information sur les groupes trouvée pour l'hôte." return 1 fi # Traitement des groupes et affichage des détails process_fog_groups "$host_groups" # Accès aux variables d'environnement pour chaque groupe for i in $(seq 1 $((group_index - 1))); do echo "Nom du groupe $i: ${!FOG_GROUP_NAME_$i}" echo "ID du groupe $i: ${!FOG_GROUP_ID_$i}" done # Affichage des détails echo "---------------------------------------" echo "Détails de l'hôte pour: $fog_hostname" echo "---------------------------------------" echo "Détails de l'hôte récupérés :" echo "$local_host" echo "---------------------------------------" # Afficher le contenu de host_groups => ALL GROUPS echo "---------------------------------------" echo "ALL GROUPS :" echo "$host_groups" echo "---------------------------------------" # Affichage des détails du groupe AUTOMATION #echo $FOG_GROUP_NAME_AUTOMATE #echo $FOG_GROUP_NAME_ID echo "Détails du groupe automation" echo "Nom du groupe: $FOG_GROUP_NAME_AUTOMATE" echo "ID du groupe: $FOG_GROUP_NAME_ID" echo "---------------------------------------" # Définir les variables d'environnement pour le nom et l'ID du groupe export FOG_GROUP_NAME_AUTOMATE export FOG_GROUP_NAME_ID } GetInfo_host SITE_GROUP="${FOG_GROUP_NAME_AUTOMATE##*_}" echo "Target Site $SITE_GROUP" echo "Try to copy this folder if existing : /images/Sites/$SITE_GROUP" # Vérification de la présence du disque système echo "Verifying we've found the OS disk" if [[ ! -d /ntfs/windows && ! -d /ntfs/Windows && ! -d /ntfs/WINDOWS ]]; then echo "! OS root Not found !" # Assurez-vous que 'debugPause' est défini, sinon utilisez une alternative appropriée # debugPause exit 1 fi echo "Found" # Préparer le chemin des dossiers clientfolderpath="/ntfs/FOG/Sites/$SITE_GROUP" remotefolderpath="/images/Sites/$SITE_GROUP" # Créer le répertoire /tmp/sites s'il n'existe pas déjà if [[ ! -d /tmp/sites ]]; then mkdir -p /tmp/sites fi # Créer le sous-répertoire avec le nom contenu dans $SITE_GROUP if [[ -n "$SITE_GROUP" ]]; then mkdir -p "/tmp/sites/$SITE_GROUP" echo "Le répertoire /tmp/sites/$SITE_GROUP a été créé." else echo "Erreur : \$SITE_GROUP est vide. Impossible de créer le répertoire." exit 1 fi # Créer le répertoire clientfolderpath s'il n'existe pas déjà if [[ ! -d "$clientfolderpath" ]]; then mkdir -p "$clientfolderpath" echo "Répertoire client créé : $clientfolderpath" fi # Copier le dossier avec rsync echo -n "In Progress" rsync -aqz "$remotefolderpath/" "$clientfolderpath/" >/dev/null 2>&1 if [[ $? -eq 0 ]]; then echo "Dossier copié avec succès." else echo "Erreur : Échec de la copie du dossier." exit 1 fi debugPause
    • H

      Solved Can't Change Hostname

      FOG Problems
      • • • HorizonG
      5
      0
      Votes
      5
      Posts
      195
      Views

      H

      @HorizonG

      Hello Sorry for the late reply, but I’ve deleted the host concerned and the problem is gone.

    • H

      Unsolved FOG Golden Image, Sysprep and unattend post install

      Windows Problems
      • • • HorizonG
      4
      0
      Votes
      4
      Posts
      702
      Views

      george1421G

      @HorizonG said in FOG Golden Image, Sysprep and unattend post install:

      ’d also try renaming the post as explained:
      with the command: sed -i “/ComputerName/s/*/$hostname/g” $unattend >/dev/null 2>&1

      The variable $hostname comes from FOG, the variable $unattend must come from your script to define the location of the unattend file on the target hard drive.

      Something to know, If you are questioning if each script is being called, place an echo some text at the top of each script. This way you can see each script being called.

      One other tip I use for debugging post install scripts is to run a deployment in debug mode. Schedule a deployment, but before you hit the schedule task button tick the debug checkbox. Now schedule the task. PXE boot the target computer you will be met with several screens of text that you need to clear with the enter key. This will drop you at the fos linux command prompt. Now key in fog to start single stepping through the deployment. At the end of the image push you should see the post install scripts executing. If you use the debugPause; command at certain locations in your script you can stop the execution and wait to press enter. If you were to hit the ctrl-c key you can exit the deploy process. What this will do is give you the exact environment where your script is running. You can try different commands or fix the post deployment scripts. If you enter the command fog again you can restart the deployment process again without rebooting.

      One last tip is that when you are interacting with the deployment process you are executing on screen 1, if you need command shell access you can press alt-f2 to go screen 2 run some comands and then pop back to screen 1 with alt-f1 to continue your script.

      The pather location is the location where microsoft recommends you place the unattend.xml file, because it will look for the file there first. Where you get things confused is if you have an unattend.xml file in both locations because it will aways use the pather location first.

    • H

      FOG Post Install, Sysprep, unattend file

      General
      • • • HorizonG
      2
      0
      Votes
      2
      Posts
      625
      Views

      JJ FullmerJ

      @HorizonG Short answer to both, yes.

      There’s a bit of work to do to make it work but you can.
      The first thing to know to help in full is what phase of sysprep you captured at?

      If you captured right after the generalize phase (best practice) and specialize is what starts you can indeed update the unattend file dynamically with computer name, domain, ou, etc.
      You can only effect the phases that haven’t happened yet. So you can add things to the specialize and oobe phases. Specialize does things before windows fully loads, it’s essentially a winpe environment, and oobe is the full windows where you can have a setupcomplete run. I have it kick off a series of powershell scripts (essentially).

      Windows also moves the unattend file around across the phases, when I update the unattend file in a post install script I just update it in all these places. i.e. in the context of fog having mounted 😄 at /ntfs
      "/ntfs/Windows/System32/Sysprep/Unattend.xml" "/ntfs/Windows/Panther/unattend.xml" "/ntfs/Windows/Panther/Unattend.xml"

      I also have one at C:\Unattend.xml you’ll see in my example below.

      Also note that it’s case sensitive, which is why I have 2 in the same spot as I’ve seen it both ways.

      I don’t have time to dig into too much detail right now but here’s an example of injecting some stuff into the unattend files. I also included my bit where I can just patch in an updated Unattend.xml file, though this wouldn’t scale for every host I just use it for another option before recapturing a whole image to test an unattend change.

      One very important bit for this to work as it does in the example is I have this bit in my specialize phase, which I replace with computername and AD info, replace NETBIOSDOMAINNAME with your short domain name that you use for this format logon string domain\username

      <component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Identification> <JoinWorkgroup>NETBIOSDOMAINNAME</JoinWorkgroup> </Identification> </component>

      I also have <ComputerName></ComputerName> in the specialize phase under my "Microsoft-Windows-Shell-Setup" component i.e. the end of this has that. I took out my company info from this example, you don’t need all of this the same, just a contextual example. The product key is the GVLK for windows 10/11 publicly available.

      <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <DesktopOptimization> <GoToDesktopOnSignIn>true</GoToDesktopOnSignIn> <ShowWindowsStoreAppsOnTaskbar>true</ShowWindowsStoreAppsOnTaskbar> </DesktopOptimization> <BluetoothTaskbarIconEnabled>true</BluetoothTaskbarIconEnabled> <ConvertibleSlateModePromptPreference>1</ConvertibleSlateModePromptPreference> <CopyProfile>false</CopyProfile> <DisableAutoDaylightTimeSet>false</DisableAutoDaylightTimeSet> <EnableStartMenu>true</EnableStartMenu> <OEMName>Company Name</OEMName> <RegisteredOrganization>Company Name</RegisteredOrganization> <ShowPowerButtonOnStartScreen>true</ShowPowerButtonOnStartScreen> <RegisteredOwner>Company Name</RegisteredOwner> <SignInMode>2</SignInMode> <TimeZone>Mountain Standard Time</TimeZone> <OEMInformation> <SupportURL>http://helpme.company.tld</SupportURL> <Logo>C:\img\company-logo.bmp</Logo> <SupportPhone>555-5555</SupportPhone> <SupportProvider>String that shows up in sys info</SupportProvider> <Manufacturer>string that shows up in sys info</Manufacturer> </OEMInformation> <Themes> <BrandIcon>C:\img\company-logo.png</BrandIcon> <ThemeName>Company Theme</ThemeName> <DesktopBackground>%WINDIR%\web\Wallpaper\some-injected-background.jpg</DesktopBackground> <WindowColor>Automatic</WindowColor> <DefaultThemesOff>false</DefaultThemesOff> </Themes> <DoNotCleanTaskBar>true</DoNotCleanTaskBar> <AutoLogon> <Password> <Value>supersecretencryptedpassword</Value> <PlainText>false</PlainText> </Password> <Enabled>true</Enabled> <Username>Administrator</Username> <LogonCount>99</LogonCount> </AutoLogon> <ProductKey>NPPR9-FWDCX-D2C8J-H872K-2YT43</ProductKey> <ComputerName></ComputerName> </component>

      The fog post download examples. I also do something with the device form setting but I tried to just take that out for this example. Device form is mildly helpful for configuring the tablet vs desktop user experience if you have a mix of such devices.

      unattends=("/ntfs/Unattend.xml" "/ntfs/Windows/System32/Sysprep/Unattend.xml" "/ntfs/Windows/Panther/unattend.xml" "/ntfs/Windows/Panther/Unattend.xml") for unattend in ${unattends[@]}; do [[ ! -f $unattend ]] && break #as a failsafe, reload the funcs.sh from fog . /usr/share/fog/lib/funcs.sh dots "Preparing Sysprep File at $unattend" #update unattend files if an Unattend.xml file is present to replace current file if [[ -f "/images/drivers/Unattend.xml" ]]; then echo -en "\n\nUnattend.xml patch file detected, updating the Unattend.xml file baseline\n\n"; echo -en "\n\nUnattend.xml patch file detected, updating the Unattend.xml file baseline\n\n" >> $updateUnattendLog rsync -aqzz "/images/drivers/Unattend.xml" $unattend; else echo -en "\n\nNo Unattend.xml patch file detected, skipping update of unattend.xml file baseline and just updating contents\n\n"; echo -en "\n\nNo Unattend.xml patch file detected, skipping update of unattend.xml file baseline and just updating contents\n\n" >> $updateUnattendLog fi #echo "File update Done" debugPause if [[ $adon=="1" ]]; then cp $unattend $unattend.old domainJoinStr="<JoinDomain></JoinDomain>\n\t\t<MachineObjectOU></MachineObjectOU>\n\t\t<Credentials>\n\t\t\t<Domain></Domain>\n\t\t\t<Password></Password>\n\t\t\t<Username></Username>\n\t\t</Credentials>" echo -en "\n\nInjecting Unattend Join fields into unattend for Dynamic update....\n" echo -en "\n\nInjecting Unattend Join fields into unattend for Dynamic update....\n" >> $updateUnattendLog # get the value of the workgroup to set as the netbios domain for the domain login netbiosdomain=`sed -n '/JoinWorkgroup/{s/.*<JoinWorkgroup>//;s/<\/JoinWorkgroup.*//;p;}' $unattend` #replace the workgroup join string with the domain tags to be updated sed -i -e "s|<JoinWorkgroup>${netbiosdomain}</JoinWorkgroup>|${domainJoinStr}|g" $unattend >/dev/null 2>&1 echo -en "\n\nSetting Dynamic Unattend fields - \n\nComputer Name: ${hostname}\nJoining Domain: ${addomain}\nWill be in OU: ${adou}\n" echo -en "\n\nSetting Dynamic Unattend fields - \n\nComputer Name: ${hostname}\nJoining Domain: ${addomain}\nWill be in OU: ${adou}\n" >> $updateUnattendLog sed -i \ -e "s|<ComputerName></ComputerName>|<ComputerName>${hostname}</ComputerName>|g" \ -e "s|<Name>\*</Name>|<Name>${hostname}</Name>|g" \ -e "s|<Password></Password>|<Password>${adpass}</Password>|g" \ -e "s|<Username></Username>|<Username>${aduser}</Username>|g" \ -e "s|<Domain></Domain>|<Domain>${netbiosdomain}</Domain>|g" \ -e "s|<MachineObjectOU></MachineObjectOU>|<MachineObjectOU>${adou}</MachineObjectOU>|g" \ -e "s|<JoinDomain></JoinDomain>|<JoinDomain>${addomain}</JoinDomain>|g" $unattend >/dev/null 2>&1 if [[ ! $? -eq 0 ]]; then echo -en "\n\nFailed to update user, pass, ou, and domain setter, set just computername and deviceform instead and using simplified unattend file\n" echo -en "\n\nFailed to update user, pass, ou, and domain setter, set just computername and deviceform instead and using simplified unattend file\n" >> $updateUnattendLog echo -en "\n\Restoring unattend file from before domain join attempt\n" echo -en "\n\Restoring unattend file from before domain join attempt\n" >> $updateUnattendLog mv $unattend.old $unattend -f echo -en "\n\nSetting Dynamic Unattend fields - \n\nDeviceForm: ${DeviceForm}\nComputer Name: ${hostname}" echo -en "\n\nSetting Dynamic Unattend fields - \n\nDeviceForm: ${DeviceForm}\nComputer Name: ${hostname}" >> $updateUnattendLog debugPause sed -i \ -e "s|<ComputerName></ComputerName>|<ComputerName>${hostname}</ComputerName>|g" \ -e "s|<Name>\*</Name>|<Name>${hostname}</Name>|g" $unattend >/dev/null 2>&1 if [[ ! $? -eq 0 ]]; then echo -en "\nFailed again after using failsafe unattend\n" echo -en "\nFailed again after using failsafe unattend\n" >> $updateUnattendLog debugPause handleError "Failed to update user, pass, ou, and domain setter and then failed the failsafe with no domain" fi else echo -en "\n\nRemoving Workgroup join section and backup unattend as adding domain join was a success...\n" echo -en "\n\nRemoving Workgroup join section and backup unattend as adding domain join was a success...\n" >> $updateUnattendLog rm -f $unattend.old sed -i "/<JoinWorkgroup>/d" $unattend >/dev/null 2>&1 sed -i "/<MachinePassword>/d" $unattend >/dev/null 2>&1 if [[ ! $? -eq 0 ]]; then echo "Failed" debugPause handleError "Failed to remove the Workgroup setter" fi fi echo -en "\n\nDone updating $unattend\n" echo -en "\n\nDone updating $unattend\n" >> $updateUnattendLog debugPause else echo -en "\n\nNo domain to join variable present, just setting deviceform and computer name and using simplified unattend file\n" echo -en "\n\nNo domain to join variable present, just setting deviceform and computer name and using simplified unattend file\n" >> $updateUnattendLog echo -en "\n\nSetting Dynamic Unattend fields - \n\nDeviceForm: ${DeviceForm}\nComputer Name: ${hostname}" echo -en "\n\nSetting Dynamic Unattend fields - \n\nDeviceForm: ${DeviceForm}\nComputer Name: ${hostname}" >> $updateUnattendLog debugPause sed -i \ -e "s|<ComputerName></ComputerName>|<ComputerName>${hostname}</ComputerName>|g" \ -e "s|<Name>\*</Name>|<Name>${hostname}</Name>|g" $unattend >/dev/null 2>&1 if [[ ! $? -eq 0 ]]; then echo "Failed" debugPause handleError "Failed to set workgroup join fields" fi fi done
    • 1 / 1