@rogerdodger wait, I just read this bit, not reimaging it makes it difficult. You still could use snapins and the fog client, but fully automating it would require reimaging.
Posts made by JJ Fullmer
-
RE: How to use unattended script to complete oobe without loading a new image
-
RE: How to use unattended script to complete oobe without loading a new image
@rogerdodger If all your SD card is doing is running ppkg files, those can be applied with powershell in a snapin, in some instances you can embed such in the image but usually best to do it after, during we’ll provisioning.
So you can probably make a simple snapin that uses powershell and the install-provisioningpackage command that references each ppkg file which you upload as the snapin file. There are some other ways you can go about it, it won’t work out of the box, but you can build a pretty robust automation solution with fog at the core.
You could also embed the ppkgs or a script that downloads the most up to date version from an internal source and have it as part of a setupcomplete.cmd or synchronous commands in an unattend xml
I’m on a phone at the moment, but if you want to go down this road I will gladly help you get started
-
RE: fog install ubuntu problem
@theyikes Why do you need to reset it to the original installation state repeatedly?
How to do that is in the wiki here https://wiki.fogproject.org/wiki/index.php/Uninstall_FOG (that doc isn’t yet migrated to the new docs site)I’m not sure why you’re wanting to start the server side fresh though.
The general idea is
- Create Fog Server on a linux vm/machine that has enough storage for the OS images (not isos, captures of install states)
- Setup a different VM with the OS as ‘golden image’ (With windows you need to utilize sysprep)
- Register that VM as a host in FOG and capture the image.
- Deploy the image to as many other hosts as you desire
See also :
https://docs.fogproject.org/en/latest/capture-an-image
https://docs.fogproject.org/en/latest/deploy-an-image
https://docs.fogproject.org/en/latest/intro -
RE: Scheduled Tasks - New Image with Task/current-Date
@Tom-Elliott @paranoid64
Just to offer another use case for this, if I’m understanding it right. We currently maintain a ‘prev’ version of our image as a separate image.
The idea being if something is wrong with the new ‘stable’ image we can quickly revert to using the ‘prev’ image and continue on.
If when capturing it automatically kept the previous version, we wouldn’t need to manually do that. We don’t actually capture to the prev image, we just created the image definition and manually do a copy of the image on the server before capturing a new stable version.
We typically align this with the windows YYH2 releases.We could probably do away with our prev image step if the stable image had an automatic history. I mean sure we have snapshot backups of our fog server too if we need it, but it’s always nice to have it at the file level for a quicker restore.
I could see other users wanting that built-in backup copy. But even still I would make it an optional setting to turn on and off, not everyone will have the storage space for 2-3 versions of their image.
-
RE: FOG Post Install, Sysprep, unattend file
@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
-
RE: 1.6.0-alpha.1377 not showing available images on host
@Tom-Elliott @sideone @MatMurdock
I can confirm this is fixed in the latest -
RE: 1.6.0-alpha.1377 not showing available images on host
@sideone @MatMurdock @Tom-Elliott
I just tested this and I’m getting the same thing too. This was working previously, we’ll work it out. -
RE: 1.6.0-alpha.1377 not showing available images on host
First I would ask you to check the php error log
cat /var/log/php-fpm/www-error.log
And post any relevant errors or warnings occurring at the same time this happens.Then 2 things I would try
I’d start with trying ipxe.efi instead of snponly.efi. I don’t remember if the kernel is loaded at that point so a different pxe boot file could help.
The other thing to do is update the kernel and Init to the latest “experimental” versions. There’s a wizard to do it in the gui for both under the configuration menu. Then give it another go.
-
RE: Restrict access to web management UI?
@fogcloud Pxe boot has to get to the boot.php file. It does this over port 80 or 443 if you have https enforced. When you enforce https ipxe is compiled with the fog ca and the certificate generated by said ca as trusted certs within your local version of ipxe.
I’m not quite sure what you mean by restricting access only to the web UI. Do you mean close all other ports? Because that will likely break tftp and nfs as they use other ports and imaging and pxe boot will be broken. ipxe itself will be fine if you’ve booted to it outside of native pxe boot where the ipxe boot file (i.e. ipxe.efi or snponly.efi) is downloaded via tftp. ipxe then downloads the boot.php file from the fog web server and boots to it to get to the fog pxe menu. -
RE: Group Management Settings not saving
@MatMurdock You can also do a full host registration and that allows you to set the group and the snapin associations at registration and kick off the image from there.
I use the API powershell module (see my signature) and have created custom functions and powershell tools to manage most my assignments. That takes a bit more work to get setup at scale but gives you more customization options.
Starting fresh, well depends on how fresh, the best answer depends on how you’re going to use Fog. Like if these are all brand new computers that aren’t in any other system yet, then doing quick reg on them all might be best.
I myself do full registration and inventory for new hosts. If all your computers already exist on the network or in Active Directory you could get the host information and import. Many moons ago I made this host scanner example https://forums.fogproject.org/topic/9560/creating-a-csv-host-import-from-a-network-scan?_=1721413305258 that will create a csv of all hosts and their macs on your network in the provided subnets.
If you can get them all in before hand, then mass-setting the snapins would be much easier. -
RE: Group Management Settings not saving
@MatMurdock A newly imaged machine will automatically deploy any assigned snapins.
The design is flexible and you can do it in many different ways but here’s a general example that would utilize a group.
- You have a group named ‘Group A’ with computers you want to image with the same image and join the domain in the same ou and have them use the same bunch of snapins
- You assign the image via group management, they all now have the same image
- You assign the AD information, they all now have the same AD info
- You assign some snapins, they all now have those snapins assigned (in addition to anything else those hosts already have assigned, you could also do a group remove of all snapins first if desired)
- You push the task to deploy or multicast deploy on the group
- All the machines in that group now have a deploy task for the image and a deploy task for the snapins associated
-
RE: Fog Client replaced powershell script with "Please update your FOG Client, this is old and insecure"
@MatMurdock That is correct.
If git pull gives you trouble (sometimes happens on upgrades) then do this within your git folder (i.e. /root/fogproject)git fetch --all git checkout working-1.6 git reset --hard origin/working-1.6 git pull
Then the cd bin and installfog.sh are good.
Also lols to CrowdStrike
-
RE: Group Management Settings not saving
@MatMurdock Are you using the persistent groups plugin? When you set something in group management I believe it doesn’t save persistently unless you’re using that plugin. The idea is that you’re setting that settings on all hosts in that group the one time. I might be remembering that wrong, but that’s what I recall.
-
RE: NVMe PCIe : BSOD after imaging "INACCESSIBLE_BOOT_DEVICE"
@nathan67 That sounds like the image doesn’t have the nvme driver.
There’s a potential easy solution, first check the bios settings on the nvme machine, if there are settings for intel VMD or intel optane make sure those are off. They require a different storage driver that isn’t including by default in windows.You could also try recapturing the image from the nvme based machine
The more complicated solution involves recapturing the image and ensuring you use sysprep and add a set of basic storage drivers that don’t get wiped so they’re embedded and at the ready for multiple use cases. If the other options don’t work I can find some time to help with that. If it requires the intel vmd driver though, I’ve had experiences where that driver makes older non-vmd intel chipsets fail to boot. So I eventually gave up on having VMD enabled, it’s a pretty sweet feature and can add some performance, but not enough to matter for the operational complexity within a controlled and mixed business environment (at least that’s what I went with for me).
-
RE: My drivers can't install
@IT-MAN
Where are you capturing your image and are you using sysprep to generalize the image without any drivers?The only way for driver injection to work on the windows side automatically is to use sysprep via an unattend.xml. Well I guess technically setupcomplete.cmd may run after setup without it according to https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/add-a-custom-script-to-windows-setup?view=windows-11 but utilize sysprep and an unattend.xml is far more robust.
It is possible to inject just the driver files into the disk in a post download script but without sysprep to kick it off, you can run into issues.
This requires capturing your image with sysprep and an unattend.xml. One thing you can do with unattend.xml is remove the drivers from the image so that conflicting drivers don’t exist, then you can add the pnputil portion in the specialize phase of sysprep.
This post is what I used and I added some of what I’ve done on top of it that may be of help.
https://forums.fogproject.org/topic/8889/fog-post-install-script-for-win-driver-injection
Also this one
https://forums.fogproject.org/topic/7740/the-magical-mystical-fog-post-download-scriptAt a high level, driver injection being dynamic per model has some assumptions
- You captured an image that doesn’t have model specific drivers (this is easiest when capturing from a VM and using sysprep)
- You have drivers organized within your /images nfs share
- You have a postdownload script that detects the model, finds the drivers, mounts the windows disk, and then injects them into a known path
- You have a method to kick off a script that installs the drivers into windows
- For example, I have a synchronouscommand in my specialize phase of my unattend that runs pnputil against the injected path, so drivers are loaded as early as possible in the process
-
RE: Management images problem
@alexpolytech94 I’m still a bit confused. So have you had working images with fog in the past and they suddenly stopped working?
-
RE: Host not registered" appears again and again
@paranoid64 Technically the menu is just ipxe, but when capturing or deploying images, getting hardware inventory, stuff like that you’re booting into fos which is in the kernel and init.
You can manually make a backup of the old kernel and init that can be just as easily restored. I believe in working-1.6 this happens automatically but to be safe you can just run this on your fog server linux terminalsudo mv /var/www/html/fog/service/ipxe/bzImage /var/www/html/fog/service/ipxe/bzImage.old sudo mv /var/www/html/fog/service/ipxe/init.xz /var/www/html/fog/service/ipxe/init.xz.old
To revert you can simply reverse those like this
sudo mv -f /var/www/html/fog/service/ipxe/bzImage.old /var/www/html/fog/service/ipxe/bzImage sudo mv -f /var/www/html/fog/service/ipxe/init.xz.old /var/www/html/fog/service/ipxe/init.xz
You can also name the new kernels different and specify a different kernel per host, but since this is happening before registration is recognized, it’ll be better to update globally to test it out. I am currently using the ‘experimental’ kernels in production with 0 issues.
Another thing to look at is some log files.
See if you have anything helpful in/var/log/php-fpm/www-error.log
and post it here -
RE: HP Z8 Fury G5 Workstation Desktop PXE boot
@alessandro19884 Is that working-1.6? I would update your fog server, that error should be fixed in the latest version.
-
RE: Host not registered" appears again and again
@paranoid64 Can you add the macs of the 4 intel lan ports to the host in the web ui? One of those macs may be being used to query the host. It should be able to see all of them and find the match but something is off.
You could try updating to the latest experimental kernel and init. If you update to the dev-branch or working-1.6 branch you can update the init in the web GUI or you can do it manually by downloading it from https://github.com/FOGProject/fos/releases and putting the init.xz on your server manually.
See also https://docs.fogproject.org/en/latest/manual-kernel-upgrade
The reason that might help is we recently added functionality for better handling of pass-thru macs. That’s not quite the case here, as it’s mostly for laptops that require a USB ethernet adapter to pxe boot, enabling mac address passthru in the bios/firmware of such systems now works as intended within fog with the new kernel and init as it will find the correct mac when there’s a passthru mac, but the new behavior may also benefit you here.