mirror of
https://github.com/mtan93/Installomator.git
synced 2026-03-08 05:31:53 +00:00
Compare commits
1646 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b333528379 | ||
|
|
89dfe63606 | ||
|
|
88cd4114ae | ||
|
|
b1dc94ad1d | ||
|
|
0b5495ffbf | ||
|
|
1fae99b322 | ||
|
|
c8677eddf5 | ||
|
|
40bc37c2f6 | ||
|
|
b9f8d569b6 | ||
|
|
a618c63b50 | ||
|
|
9aef18b89d | ||
|
|
0a8eeaf0f6 | ||
|
|
f0b7e579e3 | ||
|
|
e066a7c3bf | ||
|
|
7c45573a0e | ||
|
|
c26cfa24ba | ||
|
|
87b671f0e5 | ||
|
|
2b5ce2f90e | ||
|
|
fc33d2aaff | ||
|
|
bc4a612e15 | ||
|
|
b7d67e6967 | ||
|
|
8c853ddd30 | ||
|
|
fa26867583 | ||
|
|
dbcdea3a72 | ||
|
|
68d389ab7f | ||
|
|
8dbabec280 | ||
|
|
98f0fb1a77 | ||
|
|
d795598a22 | ||
|
|
afc906161a | ||
|
|
a8a1082d34 | ||
|
|
dfc9950a31 | ||
|
|
e22a7754bd | ||
|
|
2362e8a9d0 | ||
|
|
a7224fcbea | ||
|
|
2a0385d30d | ||
|
|
03177d4e9d | ||
|
|
8b19773a7f | ||
|
|
9ef19139d2 | ||
|
|
c4fbcd6f3a | ||
|
|
6ee318f655 | ||
|
|
b0bc3c3c81 | ||
|
|
f75d789322 | ||
|
|
94a1d2fc32 | ||
|
|
97f8b9ad26 | ||
|
|
b5a51c3cbf | ||
|
|
719fe6e925 | ||
|
|
651a5ce067 | ||
|
|
b1df345814 | ||
|
|
a626375906 | ||
|
|
5d968b0816 | ||
|
|
69c959c923 | ||
|
|
e88e2a56ea | ||
|
|
95901cfa6b | ||
|
|
7dabe54f18 | ||
|
|
ac874a9f28 | ||
|
|
3c8a4ff067 | ||
|
|
3364e6cf07 | ||
|
|
a4f8b65932 | ||
|
|
3748080fa7 | ||
|
|
47acb6443d | ||
|
|
e8b777babb | ||
|
|
116937a948 | ||
|
|
c36c14c2d6 | ||
|
|
01d1238b0d | ||
|
|
bf89f4b42b | ||
|
|
ec1e6e6dc9 | ||
|
|
76ee861038 | ||
|
|
3ef2b8e3fb | ||
|
|
bcf9ddf248 | ||
|
|
57fd2e57fc | ||
|
|
d01cb5fb97 | ||
|
|
180da16722 | ||
|
|
6b6ce8e23e | ||
|
|
b45c2f81ea | ||
|
|
2b67f3db9e | ||
|
|
ee02bee37c | ||
|
|
3f3f32db9b | ||
|
|
ac3815b758 | ||
|
|
2c378360c4 | ||
|
|
940fc5a0d6 | ||
|
|
b5ead8f650 | ||
|
|
6bdddff6d7 | ||
|
|
4a52d8ce46 | ||
|
|
bc85c8195e | ||
|
|
36860fd694 | ||
|
|
377e7e039c | ||
|
|
cb7c00751a | ||
|
|
1744c65773 | ||
|
|
5b9da39349 | ||
|
|
67ae307f86 | ||
|
|
f5f2c3c605 | ||
|
|
1903e8da80 | ||
|
|
0ceb8d2803 | ||
|
|
e33dbc1c6d | ||
|
|
939119da83 | ||
|
|
3f860cd2cb | ||
|
|
32327ae03a | ||
|
|
90efc9f110 | ||
|
|
d926ac34b4 | ||
|
|
44793e5b5e | ||
|
|
125cb221d3 | ||
|
|
3b44907148 | ||
|
|
758c8b4687 | ||
|
|
f62b100cfe | ||
|
|
3d304a1a29 | ||
|
|
2f4bbb2c68 | ||
|
|
a8d0f636d3 | ||
|
|
e700bbe7b7 | ||
|
|
1394d3968d | ||
|
|
33c2dd626f | ||
|
|
25ca38b95e | ||
|
|
11e953057a | ||
|
|
a7cefea5dd | ||
|
|
be62fa9895 | ||
|
|
dd3ac338b3 | ||
|
|
feedc86a0a | ||
|
|
3f41926cf9 | ||
|
|
5e1dba614a | ||
|
|
d404e93365 | ||
|
|
e0222cfe49 | ||
|
|
c955a69e47 | ||
|
|
c5ad2291e0 | ||
|
|
3d2c72a672 | ||
|
|
f87df8bd99 | ||
|
|
2a9fd6292c | ||
|
|
b7c8214b62 | ||
|
|
9faa9a17a9 | ||
|
|
e7ebeecc5b | ||
|
|
fdb717019f | ||
|
|
e3f5b2bebd | ||
|
|
ddc7a67e38 | ||
|
|
a68ac0d065 | ||
|
|
1c45e09134 | ||
|
|
82b429a4be | ||
|
|
92d7bec606 | ||
|
|
d00ddbc891 | ||
|
|
515087f7e9 | ||
|
|
0a4c8cfe6e | ||
|
|
91af2427fa | ||
|
|
24c550477a | ||
|
|
44cee15ac2 | ||
|
|
53cbc342c3 | ||
|
|
5b39697bf8 | ||
|
|
e6088a2eda | ||
|
|
938a40943e | ||
|
|
c0a850848b | ||
|
|
909a61fbe3 | ||
|
|
9c5ab45851 | ||
|
|
6c829ed0d6 | ||
|
|
96380b2f27 | ||
|
|
b061f37924 | ||
|
|
5a54cd92b6 | ||
|
|
57ed4e77f4 | ||
|
|
a01bfd7dae | ||
|
|
e5d309a9d9 | ||
|
|
1412f86e69 | ||
|
|
13d574bd0d | ||
|
|
4e003b2292 | ||
|
|
cd2637d30f | ||
|
|
a5421ad226 | ||
|
|
22170a89ae | ||
|
|
5ab42971e5 | ||
|
|
527490e72f | ||
|
|
776c955cdd | ||
|
|
7239ec454a | ||
|
|
0c4d7b0c56 | ||
|
|
9e9a65337d | ||
|
|
95bd32769c | ||
|
|
42126caa21 | ||
|
|
cee2b1d037 | ||
|
|
66d8f25847 | ||
|
|
960aa51770 | ||
|
|
d96c300cf8 | ||
|
|
6556cfd7d4 | ||
|
|
a4e12dd37f | ||
|
|
efa40d90e4 | ||
|
|
003647bab2 | ||
|
|
18b5d87760 | ||
|
|
daff74680e | ||
|
|
a9fdf6132a | ||
|
|
b7353eae7d | ||
|
|
e1fdda65fe | ||
|
|
438191e4d3 | ||
|
|
449276e587 | ||
|
|
54bf02886f | ||
|
|
72a019b38d | ||
|
|
8edcefc181 | ||
|
|
8e519b342c | ||
|
|
d1da823243 | ||
|
|
f92428de8d | ||
|
|
217486a118 | ||
|
|
5f22889951 | ||
|
|
bfaa243e4f | ||
|
|
98ebfdca7c | ||
|
|
3c6b8c8939 | ||
|
|
dd6732ce97 | ||
|
|
99bd9b78f4 | ||
|
|
baea19aa39 | ||
|
|
a929f7d2ac | ||
|
|
c981b093a2 | ||
|
|
a479c66dbe | ||
|
|
4ad76adf7b | ||
|
|
c138404604 | ||
|
|
ec45fcf945 | ||
|
|
160dd78ec9 | ||
|
|
3b098acaac | ||
|
|
c5af1a338e | ||
|
|
96f5bb15e2 | ||
|
|
32721128f6 | ||
|
|
4f5479aa18 | ||
|
|
8092b226f7 | ||
|
|
3f35f63d23 | ||
|
|
350c897c8a | ||
|
|
c1607fe63c | ||
|
|
4fa29967bc | ||
|
|
8f50f04725 | ||
|
|
2399dc5c1e | ||
|
|
dcde2e97f2 | ||
|
|
3d8ba13ca6 | ||
|
|
1155a9ee1e | ||
|
|
7458f8656b | ||
|
|
f7e2c5e000 | ||
|
|
9157d4763b | ||
|
|
4a60dcb017 | ||
|
|
6876114fdf | ||
|
|
ab6aedc460 | ||
|
|
8127c30c5e | ||
|
|
d18fd7f221 | ||
|
|
4467f2ce46 | ||
|
|
cabe867b30 | ||
|
|
e1e64d5e7e | ||
|
|
9047d5d68f | ||
|
|
cf412bda3c | ||
|
|
a2d2abf4f5 | ||
|
|
b238cec2fe | ||
|
|
916da6283e | ||
|
|
1521ade445 | ||
|
|
7d1067f379 | ||
|
|
b87c5e1ada | ||
|
|
eee730ba9c | ||
|
|
4db4ab4eef | ||
|
|
f689f7e10c | ||
|
|
78cd103121 | ||
|
|
6db51a0ab1 | ||
|
|
c3d6775d27 | ||
|
|
ee9fe1fd66 | ||
|
|
980fb61afb | ||
|
|
9b029ee174 | ||
|
|
f8b82a3c5f | ||
|
|
958cf59a64 | ||
|
|
84da5ac168 | ||
|
|
faffd059db | ||
|
|
d864c8e410 | ||
|
|
a8ba97b87e | ||
|
|
25c39caafc | ||
|
|
9c155d3fed | ||
|
|
780bc3924b | ||
|
|
759974f051 | ||
|
|
cd441c88d9 | ||
|
|
de55a96e9c | ||
|
|
dcfd7d8328 | ||
|
|
7bf47ff9e5 | ||
|
|
3d3114515a | ||
|
|
f124e2321b | ||
|
|
a3db297935 | ||
|
|
cfa05aa902 | ||
|
|
87cdb11039 | ||
|
|
b44fe47bf0 | ||
|
|
0d3831d074 | ||
|
|
834780a294 | ||
|
|
7f0ba6d690 | ||
|
|
f28f24b0cd | ||
|
|
b210d94b0c | ||
|
|
e7c72349d0 | ||
|
|
58ee21152c | ||
|
|
d46ee662cd | ||
|
|
d5cbee8cb7 | ||
|
|
f07a77de33 | ||
|
|
cfffd74cca | ||
|
|
b7b7958137 | ||
|
|
fb5e7ea2b4 | ||
|
|
819e812726 | ||
|
|
30e63cecc7 | ||
|
|
d259228aa1 | ||
|
|
78e4a8a5cb | ||
|
|
c2fbc23396 | ||
|
|
d02b2e6198 | ||
|
|
75fb56f9a5 | ||
|
|
a00997ef46 | ||
|
|
77a3bdeb8e | ||
|
|
46d47bc60f | ||
|
|
1477457155 | ||
|
|
45112e3f32 | ||
|
|
ef19aa28fe | ||
|
|
614da59311 | ||
|
|
dff9dd5a03 | ||
|
|
cc5326ce24 | ||
|
|
0656aa67e3 | ||
|
|
8862c4a1e7 | ||
|
|
52a9117de8 | ||
|
|
e1ad0c0132 | ||
|
|
92a4c4f3cb | ||
|
|
629aa22017 | ||
|
|
a094ffca67 | ||
|
|
719ca81bcb | ||
|
|
a308ccbc29 | ||
|
|
ddf5e6da29 | ||
|
|
9b5f408c8f | ||
|
|
1d49c08344 | ||
|
|
32c0cba0f2 | ||
|
|
4905091908 | ||
|
|
720128f23a | ||
|
|
19e59fc36c | ||
|
|
0063c0e025 | ||
|
|
ef3113a05f | ||
|
|
0460aa2724 | ||
|
|
2a1b7056c9 | ||
|
|
dfe9860848 | ||
|
|
84e0d5d263 | ||
|
|
18638141b6 | ||
|
|
d0d3510689 | ||
|
|
e4cff5821d | ||
|
|
9fb414958a | ||
|
|
e90dfd6d82 | ||
|
|
c04c591a03 | ||
|
|
0a9957169e | ||
|
|
72d2c4ab74 | ||
|
|
14fc1db433 | ||
|
|
5b7038bf19 | ||
|
|
6d7a64667f | ||
|
|
face2a7e93 | ||
|
|
02946d88c8 | ||
|
|
05816942cc | ||
|
|
6a2da9f55c | ||
|
|
6412c9f527 | ||
|
|
09a34c05b7 | ||
|
|
8116800835 | ||
|
|
3fd88f6207 | ||
|
|
a84b14234e | ||
|
|
66133a5520 | ||
|
|
1dfa162783 | ||
|
|
473fcb11d8 | ||
|
|
3cd367a1b0 | ||
|
|
aa4b3db04e | ||
|
|
e0c4e0ca26 | ||
|
|
4e5f069024 | ||
|
|
034e60a190 | ||
|
|
053b0a1225 | ||
|
|
4eb6a94a53 | ||
|
|
f166cf7efa | ||
|
|
60f7ee237a | ||
|
|
69bb31b3a2 | ||
|
|
fe48e4628e | ||
|
|
acb2963f7a | ||
|
|
5b46970d51 | ||
|
|
6f9d2a711d | ||
|
|
f444c9a0ba | ||
|
|
521d6e8672 | ||
|
|
ae34d5591e | ||
|
|
64cdeffb90 | ||
|
|
10afa45f5e | ||
|
|
7e515b0366 | ||
|
|
96bad4bd84 | ||
|
|
21128946ef | ||
|
|
35eb65f668 | ||
|
|
84d4184b1e | ||
|
|
158a30b6f1 | ||
|
|
ae7db2621c | ||
|
|
1ec9c3f0b0 | ||
|
|
817a3992b0 | ||
|
|
ba767cb2df | ||
|
|
6108758a2f | ||
|
|
f7f918edcb | ||
|
|
9652167833 | ||
|
|
5e0e77c346 | ||
|
|
2fd262b6cb | ||
|
|
a6f1224b41 | ||
|
|
f479413f70 | ||
|
|
9e24f2b8e8 | ||
|
|
abe2e51f13 | ||
|
|
e160bcb123 | ||
|
|
7b4b1d12d1 | ||
|
|
c219f38459 | ||
|
|
82bda85d6c | ||
|
|
4c2a49af60 | ||
|
|
650a07402f | ||
|
|
13b0e99bb8 | ||
|
|
0d30b6fb6c | ||
|
|
4040067fc7 | ||
|
|
20e6d0d122 | ||
|
|
63423f175e | ||
|
|
e56be4f18a | ||
|
|
db85295899 | ||
|
|
442a4ae0af | ||
|
|
f8b91946c6 | ||
|
|
2a236e9b2c | ||
|
|
b96e1dbca1 | ||
|
|
a22e656146 | ||
|
|
dd98c13e40 | ||
|
|
89c4d4fa5c | ||
|
|
3ccc9dc93e | ||
|
|
1de3838a9b | ||
|
|
124c0cf85f | ||
|
|
b99c2619f4 | ||
|
|
9b229085bd | ||
|
|
7e93eb6471 | ||
|
|
8789d2cd75 | ||
|
|
8e26889e29 | ||
|
|
ea6434c476 | ||
|
|
8be5f4866e | ||
|
|
ca73eca5f2 | ||
|
|
af6ab1ae56 | ||
|
|
7db13f0ecb | ||
|
|
b56276612a | ||
|
|
fa5f052d5a | ||
|
|
ed8e9ef913 | ||
|
|
08fd69ae7b | ||
|
|
4e8748d4fa | ||
|
|
8576bdffbb | ||
|
|
5cf34c8ed8 | ||
|
|
d6564d0e33 | ||
|
|
7c433785c9 | ||
|
|
db1621cfb7 | ||
|
|
84b9a98e13 | ||
|
|
e8d56b585c | ||
|
|
4420ce2cf9 | ||
|
|
f77cd4467e | ||
|
|
bd41912310 | ||
|
|
2b658a576c | ||
|
|
d3390fefe6 | ||
|
|
00a0f583b6 | ||
|
|
fc33a03447 | ||
|
|
c889a2d735 | ||
|
|
3aafdde178 | ||
|
|
05e4cc92ea | ||
|
|
9a154b80b7 | ||
|
|
1de072bdbf | ||
|
|
5c43199ee6 | ||
|
|
2efdd45759 | ||
|
|
f7d903bc87 | ||
|
|
5808bcc8dd | ||
|
|
c6dbf15995 | ||
|
|
ce857dd372 | ||
|
|
867c152ae5 | ||
|
|
27157e00c7 | ||
|
|
d580ace737 | ||
|
|
389fa83fdc | ||
|
|
83df589092 | ||
|
|
047c44b507 | ||
|
|
a73eb14436 | ||
|
|
183ad615f8 | ||
|
|
069651cf9f | ||
|
|
a1f0864b7d | ||
|
|
5eeabef079 | ||
|
|
ab86ff3a45 | ||
|
|
0ff286b701 | ||
|
|
ad5ad5f408 | ||
|
|
c9fc5d6676 | ||
|
|
e1dc3cc464 | ||
|
|
aed48ea4b4 | ||
|
|
343785781a | ||
|
|
1e8253ca41 | ||
|
|
69fbc31078 | ||
|
|
77e04922e5 | ||
|
|
ac80aa1f3a | ||
|
|
a87122409a | ||
|
|
963282dbe1 | ||
|
|
7cc01840e0 | ||
|
|
8d0f037983 | ||
|
|
abbf22455f | ||
|
|
d86aef9ede | ||
|
|
35f3b938bc | ||
|
|
fad95d156a | ||
|
|
2012395021 | ||
|
|
e21d8d4ef2 | ||
|
|
d4b2200ca9 | ||
|
|
4700957764 | ||
|
|
8ba02428a0 | ||
|
|
a3021011c0 | ||
|
|
f0a91934de | ||
|
|
412fcca624 | ||
|
|
4e31bd16a0 | ||
|
|
cbdc1c6876 | ||
|
|
e4f5b9cb47 | ||
|
|
046df34e45 | ||
|
|
fc3ba293ae | ||
|
|
e1de1433ff | ||
|
|
cd5a4b2b5e | ||
|
|
d1bb003a8d | ||
|
|
8a9a94540a | ||
|
|
d20dec9e2e | ||
|
|
6bb5fedc21 | ||
|
|
5a5addcb2e | ||
|
|
3e89333395 | ||
|
|
aa762ecee2 | ||
|
|
c89f704817 | ||
|
|
bf353dc538 | ||
|
|
07d51c3239 | ||
|
|
973de91ff4 | ||
|
|
3cf7b585ef | ||
|
|
da5585a702 | ||
|
|
9e0bfd5818 | ||
|
|
1571dec014 | ||
|
|
5477c5ccfe | ||
|
|
4f3b130b04 | ||
|
|
52ad8d9d88 | ||
|
|
2b3da07cdb | ||
|
|
259afeec3a | ||
|
|
13864a0cd7 | ||
|
|
66f3275741 | ||
|
|
b76d9fe26a | ||
|
|
4d365aa960 | ||
|
|
589747f0ad | ||
|
|
3294751e63 | ||
|
|
03f3e258e4 | ||
|
|
78eec85809 | ||
|
|
dd50a618e9 | ||
|
|
8b5f5d40c9 | ||
|
|
143967e29c | ||
|
|
ad1ddc22cd | ||
|
|
01d00aa361 | ||
|
|
f90c9c960a | ||
|
|
0141b8334e | ||
|
|
f7d822a54e | ||
|
|
ed01f6d741 | ||
|
|
63ddb9d2e7 | ||
|
|
0266f74e46 | ||
|
|
744ce4949d | ||
|
|
5dc137dcbe | ||
|
|
e464efeb82 | ||
|
|
4bfbe5e404 | ||
|
|
7e6d394c68 | ||
|
|
2589d2ec38 | ||
|
|
9307374775 | ||
|
|
8d2d82df5a | ||
|
|
026c399e0c | ||
|
|
1ce70bc8f3 | ||
|
|
9407918bd7 | ||
|
|
522b0c5bf2 | ||
|
|
9e336d1e3b | ||
|
|
24f99366cc | ||
|
|
c6470fdd79 | ||
|
|
e74d0ab413 | ||
|
|
3449c24508 | ||
|
|
902175fa09 | ||
|
|
fca59f554b | ||
|
|
a089d607ac | ||
|
|
d32c1bae9b | ||
|
|
79b2b43cd0 | ||
|
|
972a319bb9 | ||
|
|
237648004a | ||
|
|
2e291eb6c1 | ||
|
|
8b054338d9 | ||
|
|
8ff6a0f9ca | ||
|
|
0f892f5868 | ||
|
|
1c2d8d9c17 | ||
|
|
401d5ad138 | ||
|
|
3ef215c22b | ||
|
|
ed07b2af2b | ||
|
|
251b2a14a8 | ||
|
|
24bbe426ad | ||
|
|
fc58b8e5a8 | ||
|
|
b160291753 | ||
|
|
3578f9cbe9 | ||
|
|
351cc07afa | ||
|
|
229e2c76bb | ||
|
|
a27ca5a5d3 | ||
|
|
5109597f1a | ||
|
|
f8a3104470 | ||
|
|
7fa9d3c24a | ||
|
|
02435b25ad | ||
|
|
a4b02197d8 | ||
|
|
a058a6594b | ||
|
|
20e87458ad | ||
|
|
1797bb645b | ||
|
|
95684b6ecf | ||
|
|
affe0f4073 | ||
|
|
37f6290d34 | ||
|
|
cec9d53ff8 | ||
|
|
600657b074 | ||
|
|
c728c25fc4 | ||
|
|
bb935516d1 | ||
|
|
7456bdad04 | ||
|
|
38f2f45d97 | ||
|
|
034ac45ba0 | ||
|
|
f0f4ff5747 | ||
|
|
579862274a | ||
|
|
72fdc2365e | ||
|
|
ac042bc700 | ||
|
|
f001a829bd | ||
|
|
9736e1dbfa | ||
|
|
d78c6fdd5c | ||
|
|
65b16dc1ed | ||
|
|
9f5b89c37e | ||
|
|
05c1bf7cfc | ||
|
|
e07b4dd08f | ||
|
|
88da86d4f0 | ||
|
|
b512ae17a3 | ||
|
|
1787842366 | ||
|
|
3e0ad885d8 | ||
|
|
001cd592b0 | ||
|
|
de93df0f85 | ||
|
|
0d9628b587 | ||
|
|
41e828f87a | ||
|
|
eb25c271e3 | ||
|
|
25c419b50d | ||
|
|
7025efe566 | ||
|
|
22a34c45c9 | ||
|
|
cc06b77611 | ||
|
|
30f1f1b43c | ||
|
|
70c4d59df7 | ||
|
|
7fcba4cb6e | ||
|
|
00ebfa35fd | ||
|
|
2d813bce80 | ||
|
|
69e4cdd216 | ||
|
|
55eb9e2d89 | ||
|
|
2349f456bc | ||
|
|
8fd949a567 | ||
|
|
f9997623f1 | ||
|
|
4b14b31ff3 | ||
|
|
ed737510bb | ||
|
|
ec9f1bb9a2 | ||
|
|
9022d8e74d | ||
|
|
2a9b73dba7 | ||
|
|
40f20b3536 | ||
|
|
3a0c104f48 | ||
|
|
7629acf6a5 | ||
|
|
9f79cf4d65 | ||
|
|
54070273bc | ||
|
|
3d84300665 | ||
|
|
bbae9356c4 | ||
|
|
57733423b1 | ||
|
|
c3f751bad8 | ||
|
|
56bf2a3dc4 | ||
|
|
28ddefbd57 | ||
|
|
3a0373af60 | ||
|
|
fb7d9c43a8 | ||
|
|
ebed623837 | ||
|
|
b18aac905e | ||
|
|
4f1c56177a | ||
|
|
0a3b7af338 | ||
|
|
9b6c337d7a | ||
|
|
9fd2b87e3c | ||
|
|
a16cd44b0e | ||
|
|
74f6b569dd | ||
|
|
d475b2b8ab | ||
|
|
d79886b88f | ||
|
|
56125c07b1 | ||
|
|
a3dbf75818 | ||
|
|
afbd1e363e | ||
|
|
22bc0ecbf6 | ||
|
|
24f729d357 | ||
|
|
81b02e3932 | ||
|
|
800912be0c | ||
|
|
1e3a50c07f | ||
|
|
693164c9a0 | ||
|
|
fbe58f8ee3 | ||
|
|
e8948dafb3 | ||
|
|
0c12343fbb | ||
|
|
cba0e8c766 | ||
|
|
a25c904ba7 | ||
|
|
d64c18df93 | ||
|
|
9afdc233f9 | ||
|
|
bc7d005fb9 | ||
|
|
175f682b43 | ||
|
|
ff8a9c2c3a | ||
|
|
bf740d1ffe | ||
|
|
1da37a13ca | ||
|
|
b30d4da703 | ||
|
|
c3714d855c | ||
|
|
dd83f6bd75 | ||
|
|
c55cc788bb | ||
|
|
df616d2f51 | ||
|
|
557d63a4f3 | ||
|
|
0432eb62d3 | ||
|
|
071586e43c | ||
|
|
aea7d282fe | ||
|
|
cd6b1397c8 | ||
|
|
1d405de70a | ||
|
|
0645ff6335 | ||
|
|
c9d1d458f3 | ||
|
|
19c1275f12 | ||
|
|
aa53b0be68 | ||
|
|
9b58f57ae1 | ||
|
|
806c87266b | ||
|
|
7d60f0a11f | ||
|
|
435a60ac9f | ||
|
|
cf414f7dc6 | ||
|
|
ae3f711738 | ||
|
|
c238f94a9b | ||
|
|
9275e0c045 | ||
|
|
b3d3f25e19 | ||
|
|
2a1176a947 | ||
|
|
842b1e19cb | ||
|
|
d34f3102fc | ||
|
|
d74036e853 | ||
|
|
bb4a396788 | ||
|
|
4bc67f3de3 | ||
|
|
08e9e63422 | ||
|
|
378b166164 | ||
|
|
83c1911248 | ||
|
|
ee9861c0f5 | ||
|
|
516f05a4cb | ||
|
|
e181a02838 | ||
|
|
f2782989ce | ||
|
|
36fc48682e | ||
|
|
890c26e2e1 | ||
|
|
f1616d0d02 | ||
|
|
0a05b533a5 | ||
|
|
d36b42acf4 | ||
|
|
434b755946 | ||
|
|
62734a2acc | ||
|
|
29fadb78b4 | ||
|
|
3a397c5881 | ||
|
|
bbf4b22296 | ||
|
|
790dabaa27 | ||
|
|
ded71fdf8d | ||
|
|
952683310a | ||
|
|
5991ce2287 | ||
|
|
19137f6d94 | ||
|
|
fe21c1395a | ||
|
|
5b54eb7674 | ||
|
|
6559d84075 | ||
|
|
168abdb32e | ||
|
|
f53e20e313 | ||
|
|
9416700da2 | ||
|
|
dd2af4a40e | ||
|
|
bc26aa0ca6 | ||
|
|
ec2debc9a8 | ||
|
|
1e68b7e501 | ||
|
|
64a33a7f6b | ||
|
|
3bf9299218 | ||
|
|
ac9c5096cd | ||
|
|
22395d00a5 | ||
|
|
a994a8497c | ||
|
|
e7f4f86b58 | ||
|
|
621d6df346 | ||
|
|
9bd11b6826 | ||
|
|
6e76685721 | ||
|
|
64a91bff36 | ||
|
|
7d02cf1da4 | ||
|
|
2baf2abb91 | ||
|
|
5068ebcfd0 | ||
|
|
2571744a65 | ||
|
|
f2354ec755 | ||
|
|
f218889f7c | ||
|
|
449f7e5261 | ||
|
|
197e07ed99 | ||
|
|
ad4692e9bf | ||
|
|
195b7df5f5 | ||
|
|
6f4d9b5e81 | ||
|
|
4745138258 | ||
|
|
c64dced024 | ||
|
|
dd7344b838 | ||
|
|
49337a4ae8 | ||
|
|
cfaa94c51f | ||
|
|
83459a83d6 | ||
|
|
08435381a1 | ||
|
|
df40501291 | ||
|
|
197b34fe02 | ||
|
|
0f448404e2 | ||
|
|
c98fd8f26c | ||
|
|
244e4bb25a | ||
|
|
c60999ac7d | ||
|
|
dc520726f8 | ||
|
|
c7165f2154 | ||
|
|
717d7f46a6 | ||
|
|
35921e5893 | ||
|
|
fb777c7038 | ||
|
|
c7eeaeee19 | ||
|
|
d470867c10 | ||
|
|
0916d618b6 | ||
|
|
e4a5f47272 | ||
|
|
fee9394751 | ||
|
|
d2381d2053 | ||
|
|
7f2bdfb1df | ||
|
|
69372e4929 | ||
|
|
b45bb0c39a | ||
|
|
e6b58010d5 | ||
|
|
82faf74eb3 | ||
|
|
f96cd178c6 | ||
|
|
99b908f646 | ||
|
|
59c7590107 | ||
|
|
180ca0952b | ||
|
|
c0ce59a1ec | ||
|
|
a36e9fce43 | ||
|
|
da21ea8582 | ||
|
|
c8071a2a63 | ||
|
|
0fc7761fb9 | ||
|
|
4df1a6dbaa | ||
|
|
cd0204bb04 | ||
|
|
901ea4babd | ||
|
|
504e8528ce | ||
|
|
6f229b0b8c | ||
|
|
36b7148e30 | ||
|
|
0cdc780a5f | ||
|
|
59eaff7d26 | ||
|
|
8532baf8a5 | ||
|
|
9d021e012c | ||
|
|
22129c7220 | ||
|
|
ca1759abd9 | ||
|
|
1360b51eae | ||
|
|
193d51d49f | ||
|
|
bd07ee6c76 | ||
|
|
01eabca204 | ||
|
|
732181c3a6 | ||
|
|
a8c9fdbab7 | ||
|
|
27fd0b0347 | ||
|
|
3c7d570249 | ||
|
|
fe4c8a96da | ||
|
|
9603ef3552 | ||
|
|
e41cf16945 | ||
|
|
d88712be1d | ||
|
|
bb6bf1c526 | ||
|
|
4e21a99fd7 | ||
|
|
320757c747 | ||
|
|
18e3024604 | ||
|
|
188689f1fd | ||
|
|
1b6d7929d3 | ||
|
|
b61f18e6f4 | ||
|
|
899dbaa6b3 | ||
|
|
cd91fd5b2f | ||
|
|
cd1d05b21f | ||
|
|
d74eab2ae7 | ||
|
|
88367cf6b2 | ||
|
|
cced10b1c6 | ||
|
|
79cdaa2b40 | ||
|
|
4d9348761b | ||
|
|
6e5a5d0a41 | ||
|
|
02b0829877 | ||
|
|
c1734bac7f | ||
|
|
31fe45e61a | ||
|
|
9711d53d5e | ||
|
|
7e059581ad | ||
|
|
294dd3c58f | ||
|
|
ea58d0e48b | ||
|
|
85a8fd09d9 | ||
|
|
67212af6d7 | ||
|
|
a78bd9a285 | ||
|
|
791fd45bae | ||
|
|
264dc99a97 | ||
|
|
aa2f4146f7 | ||
|
|
9b47ed2e3f | ||
|
|
130764696d | ||
|
|
6a9ffeb101 | ||
|
|
a1afc4727e | ||
|
|
d80c76a4d3 | ||
|
|
c3ddd4f8c7 | ||
|
|
75e550acfe | ||
|
|
6c498dbf31 | ||
|
|
21cee3a1ba | ||
|
|
3b6e27f1fa | ||
|
|
d645985184 | ||
|
|
85c8fecc35 | ||
|
|
c499327e7d | ||
|
|
61b05ff31e | ||
|
|
1fdbef74c1 | ||
|
|
bd261b1c63 | ||
|
|
1a1ad30b66 | ||
|
|
2c4bef3524 | ||
|
|
dac472f6d1 | ||
|
|
9797da6023 | ||
|
|
c302cf6376 | ||
|
|
ff621c7916 | ||
|
|
d135ca1c4d | ||
|
|
61196b3da6 | ||
|
|
9a9d0ca906 | ||
|
|
c635a05deb | ||
|
|
ce0f23ff16 | ||
|
|
6db60dd641 | ||
|
|
77bee0a88e | ||
|
|
a4fe0d65ec | ||
|
|
9178cf8fe5 | ||
|
|
c7b5f89a4c | ||
|
|
acb785bb29 | ||
|
|
f57d946410 | ||
|
|
f7846c71d2 | ||
|
|
fd4e00d1fd | ||
|
|
304df956b9 | ||
|
|
76ca386abc | ||
|
|
259df4aa55 | ||
|
|
b885fdb742 | ||
|
|
5a34a35e86 | ||
|
|
5bf24ab7b4 | ||
|
|
886ab1238a | ||
|
|
107f39599e | ||
|
|
2ba53683df | ||
|
|
49470cdfdd | ||
|
|
b80c33320f | ||
|
|
fd2ed3aa49 | ||
|
|
dd8b9b2b16 | ||
|
|
e622c6d434 | ||
|
|
f997c702dd | ||
|
|
f87540454b | ||
|
|
98c56d505b | ||
|
|
241df209b6 | ||
|
|
dda03ae9d5 | ||
|
|
cf42f1f8b7 | ||
|
|
0b3ab7b382 | ||
|
|
52f1371042 | ||
|
|
f73b1af054 | ||
|
|
4471169fe4 | ||
|
|
72257d21ae | ||
|
|
d8dbde032a | ||
|
|
9af3408da6 | ||
|
|
26b5956894 | ||
|
|
4adbd1fd2c | ||
|
|
3dd9818d9a | ||
|
|
d7042fce29 | ||
|
|
2178caae0e | ||
|
|
f718e60269 | ||
|
|
a54c9f0dbc | ||
|
|
89dffc5989 | ||
|
|
74ff5ecb08 | ||
|
|
9cc4972f62 | ||
|
|
b43ebe3483 | ||
|
|
5fcb4174f0 | ||
|
|
2a15a2142d | ||
|
|
ade237079c | ||
|
|
4117b687e8 | ||
|
|
c6237ca193 | ||
|
|
d6a9d6707e | ||
|
|
ccc58d9dc1 | ||
|
|
7ac31c00fc | ||
|
|
6da46f30a2 | ||
|
|
4b59622348 | ||
|
|
9c060635df | ||
|
|
87f4b4e967 | ||
|
|
9923a03a12 | ||
|
|
4b87ffd5df | ||
|
|
57c5113554 | ||
|
|
25fdfc38f9 | ||
|
|
19ac07ca77 | ||
|
|
1260d9b9d1 | ||
|
|
e5c25aa867 | ||
|
|
f621d36981 | ||
|
|
bf6fda07d6 | ||
|
|
80082691b9 | ||
|
|
d50a825482 | ||
|
|
6aa32cba1c | ||
|
|
cb45cab5c7 | ||
|
|
8089187598 | ||
|
|
e8f5fd0a2a | ||
|
|
7e56354cb1 | ||
|
|
5880124676 | ||
|
|
385f9c1a04 | ||
|
|
b1801dd561 | ||
|
|
6b7c01dbaa | ||
|
|
4d71a194a8 | ||
|
|
49917fd4aa | ||
|
|
5aeb5bcec0 | ||
|
|
5bb584a2d2 | ||
|
|
a1fe87c7f7 | ||
|
|
9ae8f3c11f | ||
|
|
28d2f78465 | ||
|
|
709ee18144 | ||
|
|
876c1e96c4 | ||
|
|
305987e54a | ||
|
|
a3fe713e55 | ||
|
|
9f42fb9501 | ||
|
|
b6f0afb8ba | ||
|
|
f5fcca7b89 | ||
|
|
f02bacc71a | ||
|
|
c1312e0d01 | ||
|
|
d2f39a3b87 | ||
|
|
3e6ef1a6ee | ||
|
|
b78bc12fff | ||
|
|
f062d49bfd | ||
|
|
333b03e110 | ||
|
|
2a8bd0d2e8 | ||
|
|
996e85ad24 | ||
|
|
85cb09df34 | ||
|
|
b0b1477989 | ||
|
|
c62707cd7d | ||
|
|
38bf480a2e | ||
|
|
9125dbc5d7 | ||
|
|
04151adbfd | ||
|
|
1bfe163dff | ||
|
|
289b72c5f1 | ||
|
|
0a5f667a4f | ||
|
|
c954dab309 | ||
|
|
53c629aa15 | ||
|
|
028ed10393 | ||
|
|
891dab08d4 | ||
|
|
7f96d78946 | ||
|
|
596b9c6e28 | ||
|
|
374a32be9a | ||
|
|
32353c3852 | ||
|
|
ba7fc6468f | ||
|
|
4e8db91ff0 | ||
|
|
28d5d1de0c | ||
|
|
168d19cd56 | ||
|
|
4aa7cd7793 | ||
|
|
855101a2cd | ||
|
|
b74a06f336 | ||
|
|
09b84945ed | ||
|
|
9f34df0b4e | ||
|
|
c20ba0274b | ||
|
|
3c1e6cdf37 | ||
|
|
ecb7b0416b | ||
|
|
6258de8bef | ||
|
|
15373a35f9 | ||
|
|
bf4e7d89ec | ||
|
|
800c356b01 | ||
|
|
638f7983dd | ||
|
|
3ef4f11025 | ||
|
|
a42c624a7c | ||
|
|
ca772a6d28 | ||
|
|
a2ee2ccdde | ||
|
|
7e75683d76 | ||
|
|
51ba24f5e2 | ||
|
|
b28072fe84 | ||
|
|
d1ae2f1899 | ||
|
|
39a212bee9 | ||
|
|
ecde31ee1b | ||
|
|
d8dcf785f0 | ||
|
|
c5a719b176 | ||
|
|
1931973b54 | ||
|
|
75addfe8ea | ||
|
|
15f2add5e1 | ||
|
|
76749bb518 | ||
|
|
ca6614f591 | ||
|
|
396dbd745a | ||
|
|
2d0b4992a0 | ||
|
|
f194e62d64 | ||
|
|
8bc22afe12 | ||
|
|
6875084ca3 | ||
|
|
1d5c6d1812 | ||
|
|
1b85882aa7 | ||
|
|
94ea6bb449 | ||
|
|
dfa5df4f50 | ||
|
|
819d1ec7c4 | ||
|
|
ecdf502ba8 | ||
|
|
32c3dff48d | ||
|
|
480b49adb8 | ||
|
|
2c9085c0c5 | ||
|
|
4aa7993dc2 | ||
|
|
b0ee820828 | ||
|
|
b017b7bae9 | ||
|
|
885dcf1622 | ||
|
|
272e2738b5 | ||
|
|
dfb7d42d95 | ||
|
|
bf00b864f0 | ||
|
|
77567cdf4e | ||
|
|
57f53c647e | ||
|
|
4abe614300 | ||
|
|
709a787805 | ||
|
|
b0963fdfb9 | ||
|
|
22499f5d98 | ||
|
|
503396597e | ||
|
|
df7e98e0f2 | ||
|
|
85800fc41f | ||
|
|
cfa0d90725 | ||
|
|
7e76913add | ||
|
|
4f8f69bf76 | ||
|
|
0d4344e655 | ||
|
|
316c223346 | ||
|
|
921ba0f79e | ||
|
|
98b93f1b61 | ||
|
|
b54313a4b2 | ||
|
|
3792d0d151 | ||
|
|
638dac575d | ||
|
|
9e1f8f491d | ||
|
|
4a79790d30 | ||
|
|
d49508284f | ||
|
|
cfdb884818 | ||
|
|
7d59b37bf3 | ||
|
|
d402f46c3c | ||
|
|
c85a7a1fba | ||
|
|
b6bc0b1269 | ||
|
|
cbb1e08e26 | ||
|
|
918005477b | ||
|
|
25af719e20 | ||
|
|
e46dbe7ad3 | ||
|
|
dfd9ab1071 | ||
|
|
ea9c77045f | ||
|
|
d0e0f3e060 | ||
|
|
e93ecb52de | ||
|
|
43aa0a835c | ||
|
|
7af1ce554e | ||
|
|
4c38386c53 | ||
|
|
39f67c9e89 | ||
|
|
c40168f301 | ||
|
|
e0a0b65b80 | ||
|
|
d1923a4e7f | ||
|
|
f0ff1e6269 | ||
|
|
b6092df909 | ||
|
|
2fb80375ec | ||
|
|
796f8a4e25 | ||
|
|
310140d64f | ||
|
|
8db95578c7 | ||
|
|
ba7edf8d02 | ||
|
|
c0a0b37f7e | ||
|
|
cd27693125 | ||
|
|
adbe98718f | ||
|
|
fcde9e2e4c | ||
|
|
ded8787da5 | ||
|
|
05039ae826 | ||
|
|
7c0a4ef04a | ||
|
|
8feb2e5578 | ||
|
|
47dfa8fdf4 | ||
|
|
425722acda | ||
|
|
0b3d703e02 | ||
|
|
9e2fa65670 | ||
|
|
4b53da0fb7 | ||
|
|
bf5f5ca936 | ||
|
|
1b6d82e880 | ||
|
|
c9ca70e836 | ||
|
|
0530cba21b | ||
|
|
0adc02ba0c | ||
|
|
f16ee55ed6 | ||
|
|
a67ba0934f | ||
|
|
26ae2b3139 | ||
|
|
97ec3efedb | ||
|
|
b0ed6432f6 | ||
|
|
174a2b5a46 | ||
|
|
9edc256caa | ||
|
|
8e9488c68f | ||
|
|
5799c5d432 | ||
|
|
d97c84dd0c | ||
|
|
effd470ce7 | ||
|
|
38326e87e3 | ||
|
|
e8464c5c47 | ||
|
|
9dbac45621 | ||
|
|
db3e109c21 | ||
|
|
039de95b5c | ||
|
|
028fbd60d6 | ||
|
|
50bc2fd708 | ||
|
|
c37daf5b7b | ||
|
|
468ac0de6e | ||
|
|
c21dde0074 | ||
|
|
6267736abf | ||
|
|
7803d1afe2 | ||
|
|
54b57cc83d | ||
|
|
8077cb91b9 | ||
|
|
261c92946e | ||
|
|
28dc87fdbe | ||
|
|
33e2e829c5 | ||
|
|
968e3b3ab0 | ||
|
|
b2cd2b74be | ||
|
|
66b1f9a319 | ||
|
|
f0d3828054 | ||
|
|
4bc03223ae | ||
|
|
394b8dabdc | ||
|
|
bc046cfc07 | ||
|
|
897a85a54c | ||
|
|
2b0cb9dbc0 | ||
|
|
c8ae2aa6f0 | ||
|
|
63af53fb34 | ||
|
|
498a8a28af | ||
|
|
20be5255a7 | ||
|
|
eb501486e4 | ||
|
|
66b4769369 | ||
|
|
65b82cf20d | ||
|
|
9a57ecc66b | ||
|
|
fcbe0626da | ||
|
|
82a1ed8180 | ||
|
|
1e971cc063 | ||
|
|
49c7338e9d | ||
|
|
a74d3106c0 | ||
|
|
a4e4c38423 | ||
|
|
d603a2805b | ||
|
|
84e26c07e2 | ||
|
|
8fdfaadf6d | ||
|
|
0c0977e61f | ||
|
|
012b4db5f6 | ||
|
|
d250e5a8b9 | ||
|
|
7abcf51a55 | ||
|
|
dbf0d34ac6 | ||
|
|
f65010ecb4 | ||
|
|
8a95e02d21 | ||
|
|
e18361b36c | ||
|
|
a2305d5c8c | ||
|
|
1250812203 | ||
|
|
2829a466dc | ||
|
|
7a4feb0ee7 | ||
|
|
071947cb38 | ||
|
|
8c8ea13ad3 | ||
|
|
70337cab58 | ||
|
|
614e412f01 | ||
|
|
f5730ec79b | ||
|
|
14f3725ed9 | ||
|
|
44a64b83b9 | ||
|
|
a7ec5b9531 | ||
|
|
2b06ba1f22 | ||
|
|
ca17fa3c6b | ||
|
|
e0459f3d06 | ||
|
|
a8f3944e65 | ||
|
|
409c84b7ef | ||
|
|
d69a102334 | ||
|
|
aa761f2583 | ||
|
|
71fbb7fe0c | ||
|
|
719a78ae73 | ||
|
|
6d6c011d30 | ||
|
|
0513a2d6a5 | ||
|
|
cfaac1eb28 | ||
|
|
c97a0545d3 | ||
|
|
546c5d6aa1 | ||
|
|
3bcb9e7e32 | ||
|
|
04880d329e | ||
|
|
d167a51ee6 | ||
|
|
a87f0a6ec4 | ||
|
|
c37229d763 | ||
|
|
1d634b9a80 | ||
|
|
a481b17a78 | ||
|
|
30bd4797ae | ||
|
|
5585f8c558 | ||
|
|
21b9709f6b | ||
|
|
db5c9ded56 | ||
|
|
4859efa72f | ||
|
|
a20770314e | ||
|
|
4ddc8a7f92 | ||
|
|
400be8581e | ||
|
|
553d06826d | ||
|
|
11a06eb264 | ||
|
|
1dc42a22a4 | ||
|
|
2d48072d8e | ||
|
|
4101056ede | ||
|
|
08ede3a447 | ||
|
|
6f26c70bde | ||
|
|
cc13ed9c47 | ||
|
|
470b1dd69f | ||
|
|
4d34931be5 | ||
|
|
96b52e631f | ||
|
|
7bb757e38f | ||
|
|
b465b3fa3b | ||
|
|
37c23ff1ce | ||
|
|
ea134a68d1 | ||
|
|
61a8ae9018 | ||
|
|
1f33c6bb96 | ||
|
|
87c9aaaedc | ||
|
|
cd58fc6018 | ||
|
|
b38c49600f | ||
|
|
af08a12d49 | ||
|
|
2e72b05df1 | ||
|
|
97e8c160d2 | ||
|
|
dcba9f9eb7 | ||
|
|
bb6058c7f6 | ||
|
|
d4f2d07289 | ||
|
|
e1c75dc721 | ||
|
|
fae3384b33 | ||
|
|
0c17713751 | ||
|
|
85318cc508 | ||
|
|
301bc11d20 | ||
|
|
263e29329c | ||
|
|
54c84b2ff7 | ||
|
|
d2422653d5 | ||
|
|
e8a9fab851 | ||
|
|
31f9662022 | ||
|
|
b28901f7a9 | ||
|
|
5995135b45 | ||
|
|
9dcdcb04a1 | ||
|
|
a86863dfc0 | ||
|
|
92077590dd | ||
|
|
1a169733be | ||
|
|
c9ba1d1d6c | ||
|
|
52c6b4a86f | ||
|
|
a78b3cee06 | ||
|
|
a67b7de3ac | ||
|
|
90b06e0ac3 | ||
|
|
e5037c2e81 | ||
|
|
8e828ce1fa | ||
|
|
ab88181a2f | ||
|
|
9a7af18e0a | ||
|
|
11711da5ee | ||
|
|
da174ecf92 | ||
|
|
f0d89dbed3 | ||
|
|
8633dad7eb | ||
|
|
5c58c203b8 | ||
|
|
02635f1402 | ||
|
|
fc487a1d99 | ||
|
|
7a98549447 | ||
|
|
0742ff94ed | ||
|
|
1ca05b4688 | ||
|
|
846e6e2cb2 | ||
|
|
b402630f85 | ||
|
|
ad1bb8002d | ||
|
|
09e15ea951 | ||
|
|
b7a7f512c7 | ||
|
|
0744fa8273 | ||
|
|
9af2e809df | ||
|
|
d9ebefa4be | ||
|
|
f533e8ae41 | ||
|
|
ee6a6544a6 | ||
|
|
2910b37e69 | ||
|
|
2028abae59 | ||
|
|
f8d578a6d7 | ||
|
|
557500e214 | ||
|
|
52c5ebf4ff | ||
|
|
18e265d60b | ||
|
|
fd057b9918 | ||
|
|
00b0e4dcfd | ||
|
|
f5e800a190 | ||
|
|
5410739f99 | ||
|
|
76e1e9d0a3 | ||
|
|
84c551ee31 | ||
|
|
7b16678e95 | ||
|
|
3f9daf7fe6 | ||
|
|
93d716d954 | ||
|
|
0185827256 | ||
|
|
6e4006c842 | ||
|
|
9a7d16a735 | ||
|
|
39437b9549 | ||
|
|
253d96fa49 | ||
|
|
86e63df1a6 | ||
|
|
ab00c9c1b8 | ||
|
|
d733bbdb0d | ||
|
|
e3fc7fd90a | ||
|
|
2329cf174c | ||
|
|
63c2ac30bb | ||
|
|
59ca90759d | ||
|
|
b530eb1252 | ||
|
|
9b62d3f042 | ||
|
|
351c7e4c52 | ||
|
|
78bbdddf79 | ||
|
|
f2921ec7e7 | ||
|
|
b0fb909cd1 | ||
|
|
61324e7afc | ||
|
|
31c18118ac | ||
|
|
05635a76df | ||
|
|
a153051545 | ||
|
|
e70df5593a | ||
|
|
6b4a06e635 | ||
|
|
a5469d57d5 | ||
|
|
6e0fef436b | ||
|
|
dddcd22015 | ||
|
|
8b32bb2e66 | ||
|
|
92db29a5d0 | ||
|
|
595add91c5 | ||
|
|
50498895b2 | ||
|
|
ca777320b5 | ||
|
|
1359a691f2 | ||
|
|
ff72445dd4 | ||
|
|
d1b0536a55 | ||
|
|
02a1fcb55d | ||
|
|
9b5b4f611a | ||
|
|
dc7b9316b7 | ||
|
|
368be676a8 | ||
|
|
5f77a49cfb | ||
|
|
7c013d6de8 | ||
|
|
3f2e4ac508 | ||
|
|
088b4aab2f | ||
|
|
6a296f9858 | ||
|
|
55cd237b98 | ||
|
|
5f264ca868 | ||
|
|
dace516318 | ||
|
|
88bcc87fd7 | ||
|
|
8accb60ab2 | ||
|
|
ce25012973 | ||
|
|
969d434503 | ||
|
|
b0dd72c9dd | ||
|
|
b17f1550b2 | ||
|
|
438214a5ec | ||
|
|
631c7c2b91 | ||
|
|
cad509accd | ||
|
|
fbd029d58d | ||
|
|
0d09f1650a | ||
|
|
c2dd55744f | ||
|
|
bd4e848d60 | ||
|
|
2fbe9e810f | ||
|
|
33be8b0556 | ||
|
|
dfe0fbd58f | ||
|
|
1b7fb35b53 | ||
|
|
e64fe9fcda | ||
|
|
932013b34b | ||
|
|
bef74b6a80 | ||
|
|
16828a190f | ||
|
|
d32496e7e1 | ||
|
|
34fb0d9271 | ||
|
|
ba6d887098 | ||
|
|
0691a8d560 | ||
|
|
bc9bc74cf9 | ||
|
|
ae4589dc06 | ||
|
|
0e093dd3b5 | ||
|
|
fbc6b61add | ||
|
|
248c90bec7 | ||
|
|
8ffc4dd88b | ||
|
|
448a11a1b6 | ||
|
|
0db4b87784 | ||
|
|
24b8b435b6 | ||
|
|
a8a2eaf5f0 | ||
|
|
8487d24c05 | ||
|
|
ced90daa71 | ||
|
|
a9789f54d0 | ||
|
|
519126decd | ||
|
|
d16613ec8b | ||
|
|
5c3ba1143f | ||
|
|
1acc865a7a | ||
|
|
2946990942 | ||
|
|
76b4f579e7 | ||
|
|
b83c8d2904 | ||
|
|
61ff92ae28 | ||
|
|
4fe2c926f4 | ||
|
|
c3514d247f | ||
|
|
bd71675961 | ||
|
|
54cf6ca9b3 | ||
|
|
5c6e37dd88 | ||
|
|
0f0715e659 | ||
|
|
7c6134e781 | ||
|
|
fa6ba7cc2c | ||
|
|
c6f951a1f4 | ||
|
|
9370b7a87a | ||
|
|
6cd002206b | ||
|
|
d1afcb6d7e | ||
|
|
0c100c3959 | ||
|
|
27856d5dd8 | ||
|
|
236b6f49d7 | ||
|
|
d9ae95cf1f | ||
|
|
80a2acf560 | ||
|
|
aaaaab7e1e | ||
|
|
97c37d43fc | ||
|
|
78070d2d8e | ||
|
|
0e4ff610f8 | ||
|
|
3e0d3173b9 | ||
|
|
d29881aecc | ||
|
|
b9e430dcf8 | ||
|
|
2efe4a8f1f | ||
|
|
ace185ba3d | ||
|
|
33a4185526 | ||
|
|
93ca0f9d55 | ||
|
|
97bf988885 | ||
|
|
59c6d169ee | ||
|
|
402f6025be | ||
|
|
57db07ff91 | ||
|
|
e39e6eccaf | ||
|
|
15cf49d13b | ||
|
|
c260e68a58 | ||
|
|
4932ea6a31 | ||
|
|
d63b38f50b | ||
|
|
541f5a19fe | ||
|
|
da82105186 | ||
|
|
9fdf378357 | ||
|
|
402b676ce5 | ||
|
|
33a42b129b | ||
|
|
a11dc1a49a | ||
|
|
a47ac79804 | ||
|
|
c3ec7958c2 | ||
|
|
523883e681 | ||
|
|
f082d1e438 | ||
|
|
0fd6600358 | ||
|
|
426168db71 | ||
|
|
6073495684 | ||
|
|
0c5231786a | ||
|
|
cee856d5c8 | ||
|
|
602db7279a | ||
|
|
a93fc8d6dc | ||
|
|
1a9ac1c6e2 | ||
|
|
5f1987dea3 | ||
|
|
8fc1640e5c | ||
|
|
e0e209549f | ||
|
|
fe244a817a | ||
|
|
582bd77805 | ||
|
|
cb575db52a | ||
|
|
b963792723 | ||
|
|
3b872cf5ba | ||
|
|
789e53314d | ||
|
|
b35db33421 | ||
|
|
cde16ba6a8 | ||
|
|
8e7694c71e | ||
|
|
7750cb4597 | ||
|
|
5ec9a4e8fb | ||
|
|
3cd13bed39 | ||
|
|
7db0d68776 | ||
|
|
6f1da5ae7b | ||
|
|
76aa2bde13 | ||
|
|
40b6ef882b | ||
|
|
ced76793a3 | ||
|
|
7e0dc1bb95 | ||
|
|
b7778e70ce | ||
|
|
131b5600ab | ||
|
|
e945b6cbba | ||
|
|
be9f6064e0 | ||
|
|
cd6caf3197 | ||
|
|
a39f4037c5 | ||
|
|
b277742a79 | ||
|
|
9f93a4ab39 | ||
|
|
0da83bef86 | ||
|
|
59406e6960 | ||
|
|
de274e0e7a | ||
|
|
04c24f2dd3 | ||
|
|
dd73b719ff | ||
|
|
4c8e6ef9c3 | ||
|
|
09357742ca | ||
|
|
972e0a9dfc | ||
|
|
7695dae4c7 | ||
|
|
d6cade7561 | ||
|
|
13b94a4fa2 | ||
|
|
d7893e716a | ||
|
|
35f517d1e7 | ||
|
|
4b65fd156c | ||
|
|
b5a54357a3 | ||
|
|
f477615449 | ||
|
|
fb175e6a78 | ||
|
|
5e4664c993 | ||
|
|
0fdd721677 | ||
|
|
f7c406aaf4 | ||
|
|
dfd30e3b4b | ||
|
|
ff1917778a | ||
|
|
54b3c8e965 | ||
|
|
8c2cfa4529 | ||
|
|
d6edee95cb | ||
|
|
76f0094edc | ||
|
|
b5a980eeae | ||
|
|
539a374c51 | ||
|
|
7a61f8db43 | ||
|
|
ee5a484d39 | ||
|
|
e0b7a219b2 | ||
|
|
f83001e4b9 | ||
|
|
beba434d1d | ||
|
|
23855c4278 | ||
|
|
13c47e8403 | ||
|
|
8a050671c6 | ||
|
|
6cb033f1e4 | ||
|
|
4a9d08eb29 | ||
|
|
a40d63d5d7 | ||
|
|
f9b609315c | ||
|
|
171a90a3da | ||
|
|
0740ee0018 | ||
|
|
4b26dbc2eb | ||
|
|
1bf4ea03ec | ||
|
|
430998acd4 | ||
|
|
8d23962e14 | ||
|
|
9ad06137aa | ||
|
|
b940549613 | ||
|
|
a43951dac8 | ||
|
|
abb2fbc091 | ||
|
|
f7384a9c51 | ||
|
|
0a483127fb | ||
|
|
84a77433c0 | ||
|
|
540fb35636 | ||
|
|
f8554588de | ||
|
|
2fad7a2ba0 | ||
|
|
b857008b85 | ||
|
|
df2003a169 | ||
|
|
6616e229d8 | ||
|
|
306107330f | ||
|
|
9faa5867ed | ||
|
|
1df953a2c8 | ||
|
|
0ea206f81e | ||
|
|
fbb01e4c48 | ||
|
|
e0108277a5 | ||
|
|
4d4e22379e | ||
|
|
fc01e2f8de | ||
|
|
4283329b25 | ||
|
|
2e207f6982 | ||
|
|
b99d3b50f4 | ||
|
|
c669250d8c | ||
|
|
76a38cdffc | ||
|
|
c53e49d406 | ||
|
|
125fadd4f4 | ||
|
|
53f043ede5 | ||
|
|
3530130b48 | ||
|
|
71fe13b311 | ||
|
|
2c613803b5 | ||
|
|
edff222adc | ||
|
|
4a124f2151 | ||
|
|
977e46d33f | ||
|
|
5bfeddbecf | ||
|
|
0dd63eae75 | ||
|
|
dff5b8c61a | ||
|
|
57da0331bf | ||
|
|
96c998413f | ||
|
|
933c51e00f | ||
|
|
cd9247360a | ||
|
|
a0d93f1799 | ||
|
|
138301f61e | ||
|
|
901f99459a | ||
|
|
f653833dc2 | ||
|
|
eb802b9a95 | ||
|
|
04a2c74dd8 | ||
|
|
4d49e51789 | ||
|
|
2e07291c60 | ||
|
|
5c5dadfe9b | ||
|
|
bd49d7ca97 | ||
|
|
3d4c1b45c9 | ||
|
|
961816236f | ||
|
|
be0f0a9cd0 | ||
|
|
22bd79af0e | ||
|
|
912a0e0046 | ||
|
|
5059673fc7 | ||
|
|
8a56d05a8a | ||
|
|
65d8996118 | ||
|
|
ef27dfde6d | ||
|
|
e81c8114b4 | ||
|
|
d84ce01eb5 | ||
|
|
09d0230256 | ||
|
|
c65df61524 | ||
|
|
5dff7ee718 | ||
|
|
555a7631b9 | ||
|
|
9c96b5a764 | ||
|
|
2ddbd2ab1e | ||
|
|
ec7e479372 | ||
|
|
a32b5fc0a2 | ||
|
|
2d1777ca6e | ||
|
|
37b36c8c13 | ||
|
|
9508357243 | ||
|
|
c99aabccbb | ||
|
|
a4df3399b4 | ||
|
|
7438aa403c | ||
|
|
965cf310e4 | ||
|
|
da5f99639a | ||
|
|
65f5c57772 | ||
|
|
42ec528870 | ||
|
|
7f264733a7 | ||
|
|
0a96de8449 | ||
|
|
7d6f4db736 | ||
|
|
adf34cb6f3 | ||
|
|
8544796b75 | ||
|
|
315398b3fc | ||
|
|
d40b324a91 | ||
|
|
1bc4847402 | ||
|
|
0124a7fed1 | ||
|
|
ea2d4d47e5 | ||
|
|
56e38de821 | ||
|
|
d191b23a50 | ||
|
|
246ce74f4e | ||
|
|
39d3dfceac | ||
|
|
65d0d64127 | ||
|
|
201edabfd0 | ||
|
|
8c96d9e263 | ||
|
|
54218459a2 | ||
|
|
4c7edc2ddd | ||
|
|
5f469e0dc5 | ||
|
|
eed3681118 | ||
|
|
b4c987317a | ||
|
|
5a605172b1 | ||
|
|
51baa0636b | ||
|
|
9e42ec21f2 | ||
|
|
4c23c453b0 | ||
|
|
9e4b67efed | ||
|
|
44a4c05df6 | ||
|
|
892f715dbf | ||
|
|
cb05dfd52a | ||
|
|
7e40dc1e36 | ||
|
|
decc5274f0 | ||
|
|
ee91690a0d | ||
|
|
127866750e | ||
|
|
9e2221f943 | ||
|
|
37262f12e7 | ||
|
|
697a38b7b6 | ||
|
|
a59f965acd | ||
|
|
85dcfc70bd | ||
|
|
d0fc403323 | ||
|
|
ca57ff9de6 | ||
|
|
8b1298a148 | ||
|
|
3ca4dce814 |
13
.editorconfig
Normal file
13
.editorconfig
Normal file
@@ -0,0 +1,13 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# Unix-style newlines and whitespace cleanup
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
# shell formatting
|
||||
[*.{sh,bash,zsh}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -9,4 +9,6 @@ scratch/
|
||||
*.app
|
||||
*.tbz
|
||||
|
||||
|
||||
# do include Installomator .pkg files
|
||||
#!Installomator-*.pkg
|
||||
checkLabelCurrent.sh
|
||||
|
||||
392
CHANGELOG.md
Normal file
392
CHANGELOG.md
Normal file
@@ -0,0 +1,392 @@
|
||||
## v10
|
||||
|
||||
- updates to MDM sample scripts (#738)
|
||||
- updates to Swift Dialog integration (#717)
|
||||
- documentation updates (#711)
|
||||
|
||||
And everything from the betas ([beta1](https://github.com/Installomator/Installomator/releases/tag/v10beta1), [beta2](https://github.com/Installomator/Installomator/releases/tag/v10beta2), [beta3](https://github.com/Installomator/Installomator/releases/tag/v10beta3))
|
||||
|
||||
- new labels:
|
||||
- ibmnotifier (#716)
|
||||
- ipvisionconnect (#749)
|
||||
- logitechoptionsplus (#719)
|
||||
- lucidlink (#722)
|
||||
- mactex (#685)
|
||||
- onscreencontrol (#581)
|
||||
- projectplace (#688)
|
||||
- subethaedit (#728)
|
||||
- sublimemerge (#729)
|
||||
- venturablocker (#712)
|
||||
- vysor (#710)
|
||||
|
||||
- updated labels:
|
||||
- googleadseditor (#739)
|
||||
- openvpnconnectv3 (#750)
|
||||
- tunnelblick (#618)
|
||||
|
||||
|
||||
## v10beta3
|
||||
|
||||
- option to add item to dock if dockutil is installed (#701 requires dockutil https://github.com/kcrawford/dockutil )
|
||||
- further improvements to GitHub downloads (#691)
|
||||
- updated user dialog when app is already on the latest version (#658)
|
||||
|
||||
Plus everything from beta1 and beta2.
|
||||
|
||||
- new labels:
|
||||
- adobeacrobatprodc (#707)
|
||||
- adobereaderdc-install (#707)
|
||||
- archiwareb2go (#625, #707)
|
||||
- archiwarepst (#624)
|
||||
- bitrix24 (#661)
|
||||
- charles (#670)
|
||||
- chronoagent (#617)
|
||||
- chronosync (#616)
|
||||
- cytoscape (#689)
|
||||
- egnytecore (#655)
|
||||
- fellow (#599)
|
||||
- filemakerpro (#609)
|
||||
- fujifilmwebcam (#598)
|
||||
- gfxcardstatus (#690)
|
||||
- horos (#610)
|
||||
- inetclearreportsdesigner (#601)
|
||||
- jdk18 (#608)
|
||||
- latexit (#684)
|
||||
- nudgesuite (#633)
|
||||
- origin (#662)
|
||||
- parallelsrasclient (#607)
|
||||
- polylens (#671)
|
||||
- splashtopbusiness (#660)
|
||||
- tailscale (#620)
|
||||
- zoomoutlookplugin (#656)
|
||||
- zotero (#634)
|
||||
- zulujdk18 (#612)
|
||||
|
||||
- updated labels:
|
||||
- acroniscyberprotectconnectagent (#678)
|
||||
- adobecreativeclouddesktop (#687)
|
||||
- adobereaderdc-update (#707)
|
||||
- audacity (#708)
|
||||
- duckduckgo (#704)
|
||||
- libreoffice (#605)
|
||||
- nudge
|
||||
- obs (#692)
|
||||
- r (#702)
|
||||
- rstudio (#702)
|
||||
- screamingfrogseospider (#665)
|
||||
- vlc (#705, #606)
|
||||
- xcreds
|
||||
|
||||
|
||||
|
||||
## v10beta2
|
||||
|
||||
- fixed problem with GitHub labels (#659)
|
||||
- bz2 archive support (#659)
|
||||
- fixed WorkspaceOne support (#653)
|
||||
- updated how `aapNewVersion` is determined (#680)
|
||||
|
||||
Plus everything from v10beta1
|
||||
|
||||
- new labels:
|
||||
- abetterfinderrename11 (#552)
|
||||
- carboncopycloner (#553)
|
||||
- cocoapods (#659)
|
||||
- coconutbattery (#588)
|
||||
- cricutdesignspace (#562)
|
||||
- dynalist (#591)
|
||||
- fellow (#591)
|
||||
- flexoptixapp (#554)
|
||||
- googleadseditor (#652, #541)
|
||||
- kap (#568)
|
||||
- keepingyouawake (#549)
|
||||
- lcadvancedvpnclient (#584)
|
||||
- masv (#569)
|
||||
- merlinproject (#555)
|
||||
- mongodbcompass (#654)
|
||||
- netspot (#556)
|
||||
- relatel (#619)
|
||||
- sonicvisualiser (#575)
|
||||
- strongdm (#559)
|
||||
- synologyassistant (#557)
|
||||
- synologydriveclient (#582)
|
||||
- tencentmeeting (#570)
|
||||
- typinator (#583)
|
||||
- xcreds (#675)
|
||||
- updated labels:
|
||||
- acroniscyberprotectconnect/remotix (#664)
|
||||
- acroniscyberprotectconnectagent/remotixagent (#664)
|
||||
- awsvpnclient (#586)
|
||||
- boxtools (#589)
|
||||
- clevershare2 (#664)
|
||||
- coderunner (#664)
|
||||
- colourcontrastanalyser (#664)
|
||||
- cryptomator (#664)
|
||||
- dangerzone (#664)
|
||||
- drawio (#664)
|
||||
- golang (#664)
|
||||
- icons (#664)
|
||||
- insomnia (#664)
|
||||
- knockknock (#664)
|
||||
- libreoffice (#672)
|
||||
- macports
|
||||
- opera (#664)
|
||||
- supportapp (#664)
|
||||
- vmwarehorizonclient (#645, #511)
|
||||
- deleted/deactivated labels:
|
||||
- microsoftyammer (#664)
|
||||
- wickrme (#664)
|
||||
- wickrpro (#664)
|
||||
|
||||
|
||||
## v10beta1
|
||||
|
||||
- [swiftDialog](https://github.com/bartreardon/swiftDialog) integration (#641, #632), many thanks to @bartreardon, [sample scripts](in the MDM folder)
|
||||
- added WorkspaceOne option for LOGO (#517)
|
||||
- added function for JSON parsing with JXA (#529)
|
||||
- updated assemble.sh script to update Labels.txt when script is rebuilt (#540)
|
||||
- added a no requisite install script (#493)
|
||||
- GitHub lookup now don't use API calls, this should avoid or at least reduce rate limiting (#543)
|
||||
- fixed redundant exit codes (#643, #561)
|
||||
|
||||
NOTE: some exit codes have changed! see [Installomator Exit Codes](https://github.com/Installomator/Installomator/wiki/Installomator-Exit-Codes) for a list
|
||||
|
||||
- new labels:
|
||||
- bluejeanswithaudiodriver (#473)
|
||||
- duodevicehealth (#548)
|
||||
- googlechromeenterprise (#532)
|
||||
- ipswupdater (#545)
|
||||
- mmhmm (#571)
|
||||
- nordlayer (#419)
|
||||
- prune (#538)
|
||||
- whatroute (#560)
|
||||
- updated labels:
|
||||
- blender (#535, #622)
|
||||
- camtasia2019 (#547)
|
||||
- clickshare (#565)
|
||||
- egnyte (#500)
|
||||
- googledrive (#563)
|
||||
- grammarly (#576)
|
||||
- marathon, marathon2, marathoninfinity (#544)
|
||||
- miro (#475, #539)
|
||||
- notion (#566)
|
||||
- ringcentralapp (#550)
|
||||
- sublimetext (#593, #578, #567, #623, #626)
|
||||
- talkdeskcallbar (#536)
|
||||
- talkdeskcxcloud (#537)
|
||||
- wireshark (#585)
|
||||
|
||||
|
||||
## v9.2
|
||||
|
||||
**Note**: Both Google and Mozilla recommend using the pkg installers instead of the dmg downloads for managed deployments. So far, Installomator has provided labels for both. (`googlechrome` and `googlechromepkg` or `firefox` and `firefoxpkg`, respectively) Since there are problems with the dmg downloads, a future release of Installomator will _disable_ the `firefox` and `googlechrome` dmg labels. You should switch to using `googlechromepkg` and `firefoxpkg` labels instead.
|
||||
|
||||
- bug fix (#434)
|
||||
- documentation updates (#485, #494)
|
||||
- new labels:
|
||||
- 1password8 (#514)
|
||||
- ultimakercura
|
||||
- androidstudio (#547)
|
||||
- atextlegacy (#464)
|
||||
- camtasia2019, camtasia2020 (#499)
|
||||
- clue, cluefull (#481)
|
||||
- craftmanagerforsketch
|
||||
- displaylinkmanager (#448)
|
||||
- drawio (#480)
|
||||
- duckduckgo
|
||||
- egnytewebedit (#512)
|
||||
- filezilla (#522)
|
||||
- firefoxpkg_intl
|
||||
- flycut (#501)
|
||||
- fontexplorer (#523)
|
||||
- hype (#524)
|
||||
- idrive (#507), idrivethin (#509)
|
||||
- imageoptim (#525)
|
||||
- linear (#519)
|
||||
- macoslaps (#502)
|
||||
- mightymike
|
||||
- mindmanager (#479)
|
||||
- pika (#526)
|
||||
- propresenter7 (#394)
|
||||
- qgis-pr
|
||||
- shottr (#516)
|
||||
- slab (#487)
|
||||
- snagit2019, snagit2020, snagit2021 (#498)
|
||||
- sonobus (#490)
|
||||
- talkdeskcxcloud (#452)
|
||||
- thunderbird_intl (#497)
|
||||
- unnaturalscrollwheels (#503)
|
||||
- wechat (#510)
|
||||
- xeroxworkcentre7800 (#527)
|
||||
- zohoworkdrivegenie
|
||||
- updated labels
|
||||
- adobereaderdc-update, adobereaderdc (#503)
|
||||
- amazoncorretto8jdk (#461)
|
||||
- camtasia (#499)
|
||||
- citrixworkspace (#508)
|
||||
- dbeaverce (#450)
|
||||
- dropbox
|
||||
- firefox, firefox_da, firefox_intl (#495), firefoxesr_intl (#496), firefoxpkg
|
||||
- googlechrome, googlechromepkg (#484)
|
||||
- gpgsuite (#465)
|
||||
- grammarly (#515)
|
||||
- logitechoptions (#478)
|
||||
- onlyofficedesktop (#454)
|
||||
- postman (#458)
|
||||
- rancherdesktop (#463)
|
||||
- remotedesktopmanagerenterprise
|
||||
- remotedesktopmanagerfree
|
||||
- ringcentralapp (#492)
|
||||
- sketch
|
||||
- snagit (#498)
|
||||
- talkdeskcallbar (#453)
|
||||
|
||||
|
||||
|
||||
## v9.1
|
||||
|
||||
|
||||
- added option for Microsoft Endpoint Manager (Intune) to `LOGO` (#446)
|
||||
- minor fixes (#427, #434, #436)
|
||||
- the `googlechrome` label now always downloads the universal version (#430)
|
||||
- new labels:
|
||||
- 1passwordcli (#429)
|
||||
- amazoncorretto8jdk (#423)
|
||||
- autodeskfusion360admininstall (#447)
|
||||
- axurerp10 (#439)
|
||||
- calcservice (#426)
|
||||
- clipy (#412)
|
||||
- dockutil (#432)
|
||||
- easyfind (#426)
|
||||
- grammarly (#444)
|
||||
- houdahspot (#426)
|
||||
- macadminspython (#431)
|
||||
- microsoftazuredatastudio (#438)
|
||||
- nanosaur (#426)
|
||||
- tembo (#426)
|
||||
- wordservice (#426)
|
||||
- xmenu (#426)
|
||||
- updated labels:
|
||||
- appcleaner (#428)
|
||||
- dialog (#435, #437)
|
||||
- googlechrome (#430)
|
||||
- microsoftdefender (#440)
|
||||
- supportapp (#426)
|
||||
- zoom and zoomgov (#426, #433)
|
||||
|
||||
|
||||
|
||||
## v9.0.1
|
||||
|
||||
- improved logging levels throughout the script #408
|
||||
- fixed a bug for `pkgindmg` style labels #408
|
||||
- changed the criteria used to locate an app in the case the it cannot be found in the default locations, this should help with some apps with similar name (Virtual Box and Box Drive, #401) #413
|
||||
- new label: WhiteBox Packages (`packages`) #415
|
||||
- modified label: `loom` (added Apple silicon download) #417
|
||||
|
||||
## v9
|
||||
|
||||
- We have moved the root check to the beginning of the script, and improved DEBUG handling with two different modes. `DEBUG=0` is still for production, and `1` is still for the DEBUG we previously knew downloading to the directory it is running from, but `2` will download to temporary folder, will detect updates, but will not install anything, but it will notify the user (almost as running the script without root before).
|
||||
- Added option to not interrupt Do Not Disturb full screen apps like Keynote or Zoom with `INTERRUPT_DND="no"`. Default is `"yes"` which is how it has worked until now.
|
||||
- `pkgName` in a label can now be searched for. An example is logitechoptions, where only the name of the pkg is given, and not the exact file path to it.
|
||||
- `LSMinimumSystemVersion` will now be honered, if the `Info.plist` in the app is specifying this. That means that an app that has this parameter in that file and it shows that the app requires a newer version of the OS than is currently installed, then we will not install it.
|
||||
- New variable `RETURN_LABEL_NAME`. If given the value `1`, like `RETURN_LABEL_NAME=1` then Installomator only returns the name of the label. It makes for a better user friendly message for displaying in DEPNotify if that is integrated.
|
||||
- Changed logic if `IGNORE_APP_STORE_APPS=yes`. Before this version a label like `microsoftonedrive` that was installed from App Store, and that we want to replace with the “ordinary” version, Installomator would still use `updateTool`, even though `IGNORE_APP_STORE_APPS=yes`. So we would have to have `INSTALL=force` in order to have the app replaced, as `updateTool` would be used. But now if `IGNORE_APP_STORE_APPS=yes` then `updateTool` will be not set, and the App Store app will be replaced. BUT if the installed software was not from App Store, then `updateTool` will not be used, and it would be a kind of a forced install (in the example of `microsoftonedrive`), except if the version is the same (where installation is skipped).
|
||||
- Added variable `SYSTEMOWNER` that is used when copying files when installing. Default `0` is to change owner of the app to the current user on the Mac, like this user was installing this app themselves. When using `1` we will put “root:wheel” on the app, which can be useful for shared machines.
|
||||
- Added option `curlOptions` to the labels. It can be filled with extra headers need for downloading the specific software. It needs to be an array, like `curlOptions=( )`. See “mocha”-software-labels.
|
||||
|
||||
Big changes to logging:
|
||||
- Introducing variable `LOGGING`, that can be either of the logging levels
|
||||
- Logging levels:
|
||||
0: DEBUG Everything is logged
|
||||
1: INFO Normal logging behavior
|
||||
2: WARN
|
||||
3: ERROR
|
||||
4: REQ
|
||||
- External logging to Datadog
|
||||
- A function to shorten duplicate lines in installation logs or output of longer commands
|
||||
- Ability to extract install.log in the time when Installomator was running, if further investigations needs to be done to logs
|
||||
|
||||
Fixes:
|
||||
- Fixed a problem with pkgs: If they were mounted with .pkg in the name, then we would find the directory and not the pkg file itself.
|
||||
- Minor fix for a check for a pkgName on a DMG. We used `ls` that would throw an error when not found, so the check was corrected.
|
||||
|
||||
## v8.0
|
||||
|
||||
- removed leading `0` from the version because it has lost all meaning (thanks to @grahampugh for the inspiration)
|
||||
- Installomator now detects when an app is already installed, and will display notifications correctly the user based on if the app was updated or installed for the first time.
|
||||
- New variables for labels that should be installed using CLI: `CLIInstaller` and `CLIArguments`. When the installer app is named differently than the installed app, then the variable `installerTool` should be used to name the app that should be located in the DMG or zip. See the label __adobecreativeclouddesktop__ to see its use.
|
||||
- `buildLabel.sh` has been improved to build GitHub software labels much easier. In essense if the URL contains github.com, then it will try to find if it's the latest version or if variable `archiveName` is needed for finding the software. Also improved messaging throughout the script, as well as handling a situation where a pkg does not include a “Distribution” file, but a “PackageInfo”.
|
||||
- MDM script extended with `caffeinate` so Mac will not go to sleep during the time it takes installomator to run. Especially during setup, this can be useful.
|
||||
- Microsoft labels with `updateTool` variable, is updated to run `msupdate --list` before running the updateTool directly. Problems have been reported that the update would fail if the `--list` parameter for the command was not run first. This should help with the Jamf agent stalling during installation.
|
||||
- Added bunch of new labels, and improved others.
|
||||
|
||||
## v0.7
|
||||
|
||||
- default for `BLOCKING_PROCESS_ACTION`is now `BLOCKING_PROCESS_ACTION=tell_user` and not `prompt_user`. It will demand the user to quit the app to get it updated, and not present any option to skip it. In considering various use cases in different MDM solutions this is the best option going forward. Users usually choose to update, and is most often not bothered much with this information. If it's absoultely a bad time, then they can move the dialog box to the side, and click it when ready.
|
||||
- script is now assembled from fragments. This helps avoid merging conflicts on git and allows the core team to work on the script logic while also accepting new labels. See the "Assemble Script ReadMe" for details.
|
||||
- We now detect App Store installed apps, and we do not replace them automatically. An example is Slack that will loose all settings if it is suddenly changed from App Store version to the "web" version (they differ in the handling of settings files). If `INSTALL=force` then we will replace the App Store app. We log all this.
|
||||
- Change in finding installed apps. We now look in /Applications and /Applications/Utilities first. If not found there, we use spotligt to find it. (We discovered a problem when a user has Parallels Windows installed with Microsoft Edge in it. Then Installomator wanted to update the app all the time, becaus spotlight found that Windows version of the app that Parallels created.)
|
||||
- Added bunch of new labels, and improved others.
|
||||
- Renamed `buildCaseStatement.sh` to `buildLabel.sh` and improved it a lot. It is a great start when figuring out how to create a new label for an app, or a piece of software. Look at the tutorials in our wiki.
|
||||
- Mosyle changed their app name from Business to Self-Service
|
||||
|
||||
## v0.6 - 2021-07-14
|
||||
|
||||
- several new and updated labels, for a total of 302
|
||||
- versionKey variable can be used to choose which Info.plist key to get the version from
|
||||
- an appCustomVersion() {} function can now be used in a label
|
||||
- with INSTALL=force, the script will not be using updateTool, but will reinstall instead
|
||||
- added quit and quit_kill options to NOTIFY
|
||||
- updated buildCaseStatement.sh
|
||||
- updated buildInstallomatorPkg.sh to use notarytool (requires Xcode 13)
|
||||
- several minor fixes
|
||||
|
||||
## v0.5 - 2021-04-13
|
||||
|
||||
- Major update and now with help from @Theile and @Isaac
|
||||
- Added additional `BLOCKING_PROCESS_ACTION` handlings
|
||||
- Added additional `NOTIFY=all`. Usuful if used in Self Service, as the user will be notified before download, before install as well as when it is done.
|
||||
- Added variable `LOGO` for icons i dialogs, use `LOGO=appstore` (or `jamf` or `mosyleb` or `mosylem` or `addigy`). It's also possible to set it to a direct path to a specific icon. Default is `appstore`.
|
||||
- Added variable `INSTALL` that can be set to `INSTALL=force` if software needs to be installed even though latest version is already installed (it will be a reinstall).
|
||||
- Version control now included. The variable `appNewVersion` in a label can be used to tell what the latest version from the web is. If this is not given, version checking is done after download.
|
||||
- For a label that only installs a pkg without an app in it, a variable `packageID` can be used for version checking.
|
||||
- Labels now sorted alphabetically, except for the Microsoft ones (that are at the end of the list). A bunch of new labels added, and lots of them have either been changed or improved (with `appNewVersion` og `packageID`).
|
||||
- If an app is asked to be closed down, it will now be opened again after the update.
|
||||
- If your MDM cannot call a script with parameters, the label can be set in the top of the script.
|
||||
- If your MDM is not Jamf Pro, and you need the script to be installed locally on your managed machines, then take a look at [Theiles fork](https://github.com/Theile/Installomator/). This fork can be called from the MDM using a small script.
|
||||
- Script `buildCaseStatement.sh` to help with creating labels have been improved.
|
||||
- Fixed a bug in a variable name that prevented updateTool to be used
|
||||
- added `type` variable for value `"updateronly"` if the label should only run an updater tool.
|
||||
|
||||
|
||||
## v0.4 - 2020-10-19
|
||||
|
||||
- you can now set script variables as an argument in the form `VARIABLE=value`. More detail on this in the README file, 'Configuration from Arguments.' (#26, #50, #72, and #73)
|
||||
- change `downloadFromGit` to match file types better (#58)
|
||||
- implemented a workaround for changed behavior of `xpath` in Big Sur (#80)
|
||||
- added an option `prompt_user_then_kill` to `BLOCKING_PROCESS_ACTION` which will kill the process after the third unsuccessful attempt to quit (#78, thanks Patrick Atoon @raptor399)
|
||||
- added several new labels for total of 116
|
||||
|
||||
|
||||
## v0.3 - 2020-07-23
|
||||
|
||||
- added several new labels for total of 98
|
||||
- removed the powershell labels, since the installer is not notarized
|
||||
- when run without any arguments, the script now lists all labels
|
||||
- changed how zips are expanded because this was broken on Mojave
|
||||
- improved logging in some statements
|
||||
- several more minor improvements
|
||||
|
||||
|
||||
## v0.2 - 2020-06-09
|
||||
|
||||
- many fixes for broken URLs and other bugs
|
||||
- the `pkgInDmg` and `pkgInZip` now search for a pkg file in the archive in case the file name varies with the version
|
||||
- notification on successful installation can be suppressed with the `NOTIFY` variable
|
||||
- Apple signed installers and apps that don’t have a Team ID are verified correctly now
|
||||
improved logging
|
||||
- several new applications: count increased from 62 in 0.1 to 87 in 0.2
|
||||
|
||||
|
||||
## v0.1 - 2020-05-12
|
||||
53
CONTRIBUTING.md
Normal file
53
CONTRIBUTING.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Contributing to Installomator
|
||||
|
||||
__Please note, that if you are contributing to this project with new labels or other suggestions in PRs, please put your changes in the files in the `fragments` sub-folder. DO NOT edit the full `Installomator.sh` script. The full script is generated from the fragments, and will be overwritten. More details on [how the script is assembled from the fragments here](https://github.com/Installomator/Installomator/tree/main/utils#how-to-assemble-installomatorsh).__
|
||||
|
||||
We try to keep the script as short as possible, and with more than 400 labels, we can save 400 lines in the script, if we do not have credit lines on each of these. So we are thankful for your contribution, but we will be removing these lines in the coming releases.
|
||||
|
||||
## Branches
|
||||
|
||||
The branch list is as follows:
|
||||
|
||||
- `release`: this branch will have the latest released version
|
||||
- `main`: (default) this branch will be the current build we are working on. It includes new and updated app labels, and critical bug fixes
|
||||
- `dev`: this will contain new and updated app labels, as well as other code changes that have the risk of significantly changing or breaking behavior
|
||||
there will be other branches for new features and testing.
|
||||
|
||||
This should allow the contributing team to release minor updates for new and updated app labels while also work on new features for the next major release.
|
||||
|
||||
With all the new branches, your local repo may get confused. If you don’t have local changes, it is easiest to delete your local repo and re-clone it. If you have local changes you want to preserve, then you should commit those to a local branch, pull the latest changes `git pull --all`, then delete the old master branch: `git branch -d master`.
|
||||
|
||||
Please make sure you branch off of main for your PRs.
|
||||
|
||||
__Thank you for contributing!__
|
||||
|
||||
## Labels
|
||||
|
||||
If you need a new label for a piece of software, please take a look [at the tutorials in the Wiki](https://github.com/Installomator/Installomator/wiki#tutorials), those can be helpful for starting out on the creation of the label.
|
||||
|
||||
We expect you to try out finding the __version__ of the software online, so that `appNewVersion` can be filled in the label. It helps a lot when the software needs update, and greatly improve user experience.
|
||||
|
||||
Please document what you found out about the __version__ of the software if it's not included. We will not accept a new label if this is not documented, we will ask about this if it was not included. This is very important for the quality and reliability of Installomator.
|
||||
|
||||
When creating a new label, please file a pull request (PR). And feel free to ask questions or make your comments about what else is needed, if we should take a look at the label, or help out in finding the version or isolating URLs or anything else. You can find [a tutorial on how to create a PR here](https://github.com/Installomator/Installomator/wiki/GitHub-howto-create-PRs).
|
||||
|
||||
Please include the log of installing this label in the description, like this:
|
||||
```
|
||||
% /Users/st/Documents/GitHub/Installomator/utils/assemble.sh software
|
||||
2021-11-24 10:07:19 software ################## Start Installomator v. 0.8.0
|
||||
2021-11-24 10:07:19 software ################## software
|
||||
2021-11-24 10:07:19 software DEBUG mode 1 enabled.
|
||||
```
|
||||
|
||||
Please have one label per PR, so we can separate these. Also if you change/fix a label.
|
||||
|
||||
__Thank you very much for your contribution!__
|
||||
|
||||
|
||||
## Issues
|
||||
|
||||
Do not create an issue just when you have a questions, but do file an issue or pull request (PR) for bugs or wrong behavior. Include the full log and include the version of Installomator you're running. When you create a PR to follow-up and solve an issue make sure to [mention the issue using the `#xxx` syntax in a commit message or comment to link the issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue).
|
||||
|
||||
Join [the MacAdmins Slack](https://macadmins.org) and find us in the `#installomator` channel for questions, support and discussions.
|
||||
|
||||
When in doubt, use the MacAdmins.org Slack as described in [README.md](https://github.com/Installomator/Installomator/)
|
||||
6990
Installomator.sh
6990
Installomator.sh
File diff suppressed because it is too large
Load Diff
453
Labels.txt
453
Labels.txt
@@ -1,43 +1,290 @@
|
||||
1password7
|
||||
1password8
|
||||
1passwordcli
|
||||
4kvideodownloader
|
||||
8x8
|
||||
abetterfinderrename11
|
||||
abstract
|
||||
acroniscyberprotectconnect
|
||||
acroniscyberprotectconnectagent
|
||||
adobeacrobatprodc
|
||||
adobebrackets
|
||||
adobeconnect
|
||||
adobecreativeclouddesktop
|
||||
adobereaderdc
|
||||
adobereaderdc-install
|
||||
adobereaderdc-install
|
||||
adobereaderdc-update
|
||||
aircall
|
||||
airserver
|
||||
airtame
|
||||
aldente
|
||||
alephone
|
||||
alfred
|
||||
alttab
|
||||
amazonchime
|
||||
amazoncorretto8jdk
|
||||
amazonworkspaces
|
||||
androidfiletransfer
|
||||
androidstudio
|
||||
anydesk
|
||||
apparency
|
||||
appcleaner
|
||||
applenyfonts
|
||||
applesfarabic
|
||||
applesfcompact
|
||||
applesfmono
|
||||
applesfpro
|
||||
applesfsymbols
|
||||
aquaskk
|
||||
archiwareb2go
|
||||
archiwarepst
|
||||
arq7
|
||||
asana
|
||||
atext
|
||||
atextlegacy
|
||||
atom
|
||||
audacity
|
||||
authydesktop
|
||||
autodeskfusion360admininstall
|
||||
autodmg
|
||||
autopkgr
|
||||
aviatrix
|
||||
awscli2
|
||||
awsvpnclient
|
||||
axurerp10
|
||||
azuredatastudio
|
||||
balenaetcher
|
||||
balsamiqwireframes
|
||||
bartender
|
||||
basecamp3
|
||||
bbedit
|
||||
bettertouchtool
|
||||
bitrix24
|
||||
bitwarden
|
||||
blender
|
||||
bluejeans
|
||||
bluejeanswithaudiodriver
|
||||
boxdrive
|
||||
boxsync
|
||||
boxtools
|
||||
brave
|
||||
bugdom
|
||||
caffeine
|
||||
cakebrew
|
||||
calcservice
|
||||
calibre
|
||||
camostudio
|
||||
camtasia
|
||||
camtasia2019
|
||||
camtasia2020
|
||||
camtasia2021
|
||||
canva
|
||||
carboncopycloner
|
||||
charles
|
||||
chatwork
|
||||
chronoagent
|
||||
chronosync
|
||||
cisdem-documentreader
|
||||
citrixworkspace
|
||||
clevershare2
|
||||
clickshare
|
||||
clipy
|
||||
closeio
|
||||
cloudya
|
||||
clue
|
||||
cluefull
|
||||
cocoapods
|
||||
coconutbattery
|
||||
code42
|
||||
coderunner
|
||||
colourcontrastanalyser
|
||||
cormorant
|
||||
craftmanager
|
||||
craftmanagerforsketch
|
||||
cricutdesignspace
|
||||
cryptomator
|
||||
cyberduck
|
||||
cytoscape
|
||||
daisydisk
|
||||
dangerzone
|
||||
darktable
|
||||
dbeaverce
|
||||
debookee
|
||||
defaultfolderx
|
||||
depnotify
|
||||
desktoppr
|
||||
detectxswift
|
||||
devonthink
|
||||
dialog
|
||||
dialpad
|
||||
discord
|
||||
diskspace
|
||||
displaylinkmanager
|
||||
docker
|
||||
dockutil
|
||||
drawio
|
||||
drift
|
||||
dropbox
|
||||
duckduckgo
|
||||
duodevicehealth
|
||||
dynalist
|
||||
easeusdatarecoverywizard
|
||||
easyfind
|
||||
egnyte
|
||||
egnytecore
|
||||
egnytewebedit
|
||||
element
|
||||
eraseinstall
|
||||
eshareosx
|
||||
etrecheck
|
||||
evernote
|
||||
exelbanstats
|
||||
exifrenamer
|
||||
fantastical
|
||||
fastscripts
|
||||
favro
|
||||
fellow
|
||||
ferdi
|
||||
figma
|
||||
filemakerpro
|
||||
filezilla
|
||||
findanyfile
|
||||
firefox
|
||||
firefox_da
|
||||
firefox_intl
|
||||
firefoxesr
|
||||
firefoxesr_intl
|
||||
firefoxesrpkg
|
||||
firefoxpkg
|
||||
firefoxpkg_intl
|
||||
flexoptixapp
|
||||
flowjo
|
||||
flux
|
||||
flycut
|
||||
fontexplorer
|
||||
front
|
||||
fsmonitor
|
||||
fujifilmwebcam
|
||||
gfxcardstatus
|
||||
gimp
|
||||
githubdesktop
|
||||
golang
|
||||
googleadseditor
|
||||
googlechrome
|
||||
googlechromeenterprise
|
||||
googlechromepkg
|
||||
googledrive
|
||||
googledrivebackupandsync
|
||||
googledrivefilestream
|
||||
googleearth
|
||||
googlejapaneseinput
|
||||
googlesoftwareupdate
|
||||
gotomeeting
|
||||
gpgsuite
|
||||
gpgsync
|
||||
grammarly
|
||||
grandperspective
|
||||
grasshopper
|
||||
gyazo
|
||||
gyazogif
|
||||
hancock
|
||||
handbrake
|
||||
hazel
|
||||
horos
|
||||
houdahspot
|
||||
hpeasyadmin
|
||||
hpeasystart
|
||||
hype
|
||||
hyper
|
||||
ibarcoder
|
||||
ibmnotifier
|
||||
icons
|
||||
idrive
|
||||
idrivethin
|
||||
iina
|
||||
imageoptim
|
||||
imazingprofileeditor
|
||||
inetclearreportsdesigner
|
||||
inkscape
|
||||
insomnia
|
||||
installomator
|
||||
installomator_theile
|
||||
intellijideace
|
||||
ipswupdater
|
||||
ipvisionconnect
|
||||
istatmenus
|
||||
iterm2
|
||||
itsycal
|
||||
jabradirect
|
||||
jamfconnect
|
||||
jamfconnectconfiguration
|
||||
jamfmigrator
|
||||
jamfpppcutility
|
||||
jamfreenroller
|
||||
jdk18
|
||||
jetbrainsclion
|
||||
jetbrainsdatagrip
|
||||
jetbrainsintellijidea
|
||||
jetbrainsintellijideace
|
||||
jetbrainsphpstorm
|
||||
jetbrainspycharm
|
||||
jetbrainspycharmce
|
||||
jetbrainsrubymine
|
||||
jetbrainstoolbox
|
||||
jetbrainswebstorm
|
||||
kap
|
||||
karabinerelements
|
||||
keepassxc
|
||||
keepingyouawake
|
||||
keka
|
||||
keybase
|
||||
keyboardmaestro
|
||||
klokki
|
||||
knockknock
|
||||
krisp
|
||||
krita
|
||||
lastpass
|
||||
latexit
|
||||
launchbar
|
||||
lcadvancedvpnclient
|
||||
lexarrecoverytool
|
||||
libreoffice
|
||||
linear
|
||||
logioptions
|
||||
logitechoptions
|
||||
logitechoptionsplus
|
||||
logseq
|
||||
loom
|
||||
lowprofile
|
||||
lucidlink
|
||||
lucifer
|
||||
lulu
|
||||
macadminspython
|
||||
maccyapp
|
||||
macfuse
|
||||
macoslaps
|
||||
macports
|
||||
mactex
|
||||
malwarebytes
|
||||
marathon
|
||||
marathon2
|
||||
marathoninfinity
|
||||
masv
|
||||
mattermost
|
||||
menumeters
|
||||
merlinproject
|
||||
microsoftautoupdate
|
||||
microsoftazuredatastudio
|
||||
microsoftazurestorageexplorer
|
||||
microsoftcompanyportal
|
||||
microsoftdefender
|
||||
microsoftdefenderatp
|
||||
microsoftedge
|
||||
microsoftedgeconsumerstable
|
||||
microsoftedgeenterprisestable
|
||||
microsoftexcel
|
||||
microsoftlicenseremovaltool
|
||||
microsoftoffice365
|
||||
microsoftofficebusinesspro
|
||||
microsoftonedrive
|
||||
@@ -48,40 +295,240 @@ microsoftremotedesktop
|
||||
microsoftsharepointplugin
|
||||
microsoftskypeforbusiness
|
||||
microsoftteams
|
||||
microsoftvisualstudiocode
|
||||
microsoftword
|
||||
mightymike
|
||||
mindmanager
|
||||
miro
|
||||
mmhmm
|
||||
mobikinassistantforandroid
|
||||
mochakeyboard
|
||||
mochatelnet
|
||||
mochatn3270
|
||||
mochatn3812
|
||||
mochatn5250
|
||||
mongodbcompass
|
||||
montereyblocker
|
||||
mowgliiitsycal
|
||||
musescore
|
||||
muzzle
|
||||
nanosaur
|
||||
netnewswire
|
||||
netspot
|
||||
nextcloud
|
||||
nomad
|
||||
nomadlogin
|
||||
nordlayer
|
||||
notion
|
||||
nudge
|
||||
nudgesuite
|
||||
nvivo
|
||||
obs
|
||||
obsidian
|
||||
odrive
|
||||
omnidisksweeper
|
||||
omnifocus3
|
||||
omnigraffle6
|
||||
omnigraffle7
|
||||
omnioutliner5
|
||||
omniplan3
|
||||
omniplan4
|
||||
omnipresence
|
||||
onionshare
|
||||
onlyofficedesktop
|
||||
onscreencontrol
|
||||
openvpnconnect
|
||||
openvpnconnectv3
|
||||
opera
|
||||
origin
|
||||
ottomatic
|
||||
overflow
|
||||
pacifist
|
||||
packages
|
||||
pandoc
|
||||
parallelsrasclient
|
||||
paretosecurity
|
||||
parsec
|
||||
pdfsam
|
||||
perimeter81
|
||||
pika
|
||||
pitch
|
||||
plantronicshub
|
||||
platypus
|
||||
plisteditpro
|
||||
polylens
|
||||
postman
|
||||
powershell
|
||||
powershell-lts
|
||||
prism9
|
||||
pritunl
|
||||
privileges
|
||||
proctortrack
|
||||
projectplace
|
||||
promiseutility
|
||||
promiseutilityr
|
||||
propresenter7
|
||||
protonvpn
|
||||
proxyman
|
||||
prune
|
||||
pycharmce
|
||||
pymol
|
||||
qgis-pr
|
||||
r
|
||||
ramboxce
|
||||
rancherdesktop
|
||||
rectangle
|
||||
redeye
|
||||
relatel
|
||||
remotedesktopmanagerenterprise
|
||||
remotedesktopmanagerfree
|
||||
remotix
|
||||
remotixagent
|
||||
resiliosynchome
|
||||
retrobatch
|
||||
ricohpsprinters
|
||||
ringcentralapp
|
||||
ringcentralclassicapp
|
||||
ringcentralmeetings
|
||||
ringcentralphone
|
||||
rocket
|
||||
rocketchat
|
||||
rodeconnect
|
||||
royaltsx
|
||||
rstudio
|
||||
santa
|
||||
scaleft
|
||||
screamingfrogseospider
|
||||
screencloudplayer
|
||||
screenflick
|
||||
sdnotary
|
||||
secretive
|
||||
sequelpro
|
||||
sfsymbols
|
||||
shield
|
||||
shottr
|
||||
sidekick
|
||||
signal
|
||||
silnite
|
||||
sirimote
|
||||
sizeup
|
||||
sketch
|
||||
sketchupviewer
|
||||
skype
|
||||
slab
|
||||
slack
|
||||
smartgit
|
||||
snagit
|
||||
snagit2019
|
||||
snagit2020
|
||||
snagit2021
|
||||
snagit2022
|
||||
snapgeneviewer
|
||||
sonicvisualiser
|
||||
sonobus
|
||||
sonos
|
||||
sonoss1
|
||||
sonoss2
|
||||
sourcetree
|
||||
splashtopbusiness
|
||||
splashtopsos
|
||||
spotify
|
||||
sqlpropostgres
|
||||
sqlprostudio
|
||||
steelseriesengine
|
||||
strongdm
|
||||
strongsync
|
||||
subethaedit
|
||||
sublimemerge
|
||||
sublimetext
|
||||
superhuman
|
||||
supportapp
|
||||
suspiciouspackage
|
||||
swiftdialog
|
||||
swiftruntimeforcommandlinetools
|
||||
sync
|
||||
synologyassistant
|
||||
synologydriveclient
|
||||
tableaudesktop
|
||||
tableaupublic
|
||||
tableaureader
|
||||
tageditor
|
||||
tailscale
|
||||
talkdeskcallbar
|
||||
talkdeskcxcloud
|
||||
taskpaper
|
||||
teamviewer
|
||||
teamviewerhost
|
||||
teamviewerqs
|
||||
techsmithcapture
|
||||
telegram
|
||||
tembo
|
||||
tencentmeeting
|
||||
textexpander
|
||||
textmate
|
||||
theunarchiver
|
||||
things
|
||||
thunderbird
|
||||
thunderbird_intl
|
||||
tidal
|
||||
toggltrack
|
||||
tom4aconverter
|
||||
torbrowser
|
||||
trex
|
||||
tunnelbear
|
||||
tunnelblick
|
||||
typinator
|
||||
typora
|
||||
ultimakercura
|
||||
umbrellaroamingclient
|
||||
uniconverter
|
||||
universaltypeclient
|
||||
unnaturalscrollwheels
|
||||
utm
|
||||
vagrant
|
||||
vanilla
|
||||
venturablocker
|
||||
veracrypt
|
||||
vimac
|
||||
virtualbox
|
||||
viscosity
|
||||
visualstudiocode
|
||||
vivaldi
|
||||
vlc
|
||||
vmwarehorizonclient
|
||||
vscodium
|
||||
vysor
|
||||
wacomdrivers
|
||||
wallyezflash
|
||||
webex
|
||||
webexmeetings
|
||||
webexteams
|
||||
wechat
|
||||
whatroute
|
||||
whatsapp
|
||||
wwdcformac
|
||||
wireshark
|
||||
wordservice
|
||||
wwdc
|
||||
xcreds
|
||||
xeroxphaser7800
|
||||
xeroxworkcentre7800
|
||||
xink
|
||||
xmenu
|
||||
xquartz
|
||||
yed
|
||||
yubikeymanagerqt
|
||||
zappy
|
||||
zeplin
|
||||
zohoworkdrive
|
||||
zohoworkdrivegenie
|
||||
zohoworkdrivetruesync
|
||||
zoom
|
||||
zoomclient
|
||||
zoomgov
|
||||
zoomoutlookplugin
|
||||
zoomrooms
|
||||
zotero
|
||||
zulujdk11
|
||||
zulujdk13
|
||||
zulujdk15
|
||||
zulujdk17
|
||||
zulujdk18
|
||||
zulujdk8
|
||||
|
||||
354
MDM/App-install SS with swiftDialog and dockutil/App VFA SS github.sh
Executable file
354
MDM/App-install SS with swiftDialog and dockutil/App VFA SS github.sh
Executable file
@@ -0,0 +1,354 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator with Dialog showing progress (and posibility of adding to the Dock)
|
||||
# Installation of software using `valuesfromarguments` to install a custom software using Installomator through GitHub
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
# Have the label been submittet in a PR for Installomator?
|
||||
# What version of Installomator is it expected to be included in?
|
||||
# Version 10.0
|
||||
|
||||
item="gfxcardstatus" # enter the software to install (if it has a label in future version of Installomator)
|
||||
|
||||
# Label variables below
|
||||
|
||||
# GitHub functions
|
||||
downloadURLFromGit() { # $1 git user name, $2 git repo name
|
||||
gitusername=${1?:"no git user name"}
|
||||
gitreponame=${2?:"no git repo name"}
|
||||
|
||||
if [[ $type == "pkgInDmg" ]]; then
|
||||
filetype="dmg"
|
||||
elif [[ $type == "pkgInZip" ]]; then
|
||||
filetype="zip"
|
||||
else
|
||||
filetype=$type
|
||||
fi
|
||||
|
||||
if [ -n "$archiveName" ]; then
|
||||
downloadURL=https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*$archiveName" | head -1 || true)
|
||||
if [[ "$(echo $downloadURL | grep -ioE "https.*$archiveName" || true)" == "" ]]; then
|
||||
#printlog "Trying GitHub API for download URL."
|
||||
downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }" || true)
|
||||
fi
|
||||
else
|
||||
downloadURL=https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1 || true)
|
||||
if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype" || true)" == "" ]]; then
|
||||
#printlog "Trying GitHub API for download URL."
|
||||
downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }" || true)
|
||||
fi
|
||||
fi
|
||||
if [ -z "$downloadURL" ]; then
|
||||
echo "could not retrieve download URL for $gitusername/$gitreponame"
|
||||
exit 1
|
||||
else
|
||||
echo "$downloadURL"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
versionFromGit() {
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
# $1 git user name, $2 git repo name
|
||||
gitusername=${1?:"no git user name"}
|
||||
gitreponame=${2?:"no git repo name"}
|
||||
|
||||
#appNewVersion=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | grep tag_name | cut -d '"' -f 4 | sed 's/[^0-9\.]//g' || true)
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g' || true)
|
||||
if [ -z "$appNewVersion" ]; then
|
||||
#echo "could not retrieve version number for $gitusername/$gitreponame"
|
||||
appNewVersion=""
|
||||
else
|
||||
echo "$appNewVersion"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Variables for label
|
||||
name="gfxCardStatus"
|
||||
type="zip"
|
||||
packageID=""
|
||||
downloadURL="$(downloadURLFromGit codykrieger gfxCardStatus)"
|
||||
appNewVersion="$(versionFromGit codykrieger gfxCardStatus)"
|
||||
versionKey=""
|
||||
expectedTeamID="LF22FTQC25"
|
||||
|
||||
# Dialog icon
|
||||
icon=""
|
||||
# icon should be a file system path or an URL to an online PNG.
|
||||
# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
|
||||
|
||||
# dockutil variables
|
||||
addToDock="1" # with dockutil after installation (0 if not)
|
||||
appPath="/Applications/$name.app"
|
||||
|
||||
# Other variables
|
||||
dialog_command_file="/var/tmp/dialog.log"
|
||||
dialogApp="/Library/Application Support/Dialog/Dialog.app"
|
||||
dockutil="/usr/local/bin/dockutil"
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill out the label variables above, and those will be included in the Installomator call, circa on line 248
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 10.0.3 : A bit more logging on succes, and change in ending Dialog part.
|
||||
# v. 10.0.2 : Improved icon checks and failovers
|
||||
# v. 10.0.1 : github-functions added. Improved appIcon handling. Can add the app to Dock using dockutil.
|
||||
# v. 10.0 : Integration with Dialog and Installomator v. 10
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
if [[ -z "$item" ]]; then
|
||||
item="$name"
|
||||
fi
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand="$1"
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> "$dialog_command_file"
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
checkCmdOutput () {
|
||||
local checkOutput="$1"
|
||||
exitStatus="$( echo "${checkOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${checkOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$checkOutput"
|
||||
#errorOutput="$( echo "${checkOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
#echo "$checkOutput"
|
||||
}
|
||||
|
||||
# Check the currently logged in user
|
||||
currentUser=$(stat -f "%Su" /dev/console)
|
||||
if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
|
||||
echo "ERROR. Logged in user is $currentUser! Cannot proceed."
|
||||
exit 97
|
||||
fi
|
||||
# Get the current user's UID for dockutil
|
||||
uid=$(id -u "$currentUser")
|
||||
# Find the home folder of the user
|
||||
userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Mark: Installation begins
|
||||
installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
|
||||
|
||||
if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion | cut -c1-2) -lt 20 ]]; then
|
||||
echo "Skipping swiftDialog UI, using notifications."
|
||||
#echo "Installomator should be at least version 10 to support swiftDialog. Installed version $installomatorVersion."
|
||||
#echo "And macOS 11 Big Sur (build 20A) is required for swiftDialog. Installed build $(sw_vers -buildVersion)."
|
||||
installomatorNotify="NOTIFY=all"
|
||||
else
|
||||
installomatorNotify="NOTIFY=silent"
|
||||
# check for Swift Dialog
|
||||
if [[ ! -d $dialogApp ]]; then
|
||||
echo "Cannot find dialog at $dialogApp"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
|
||||
# Configure and display swiftDialog
|
||||
itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
|
||||
if [[ "$itemName" != "#" ]]; then
|
||||
message="Installing ${itemName}…"
|
||||
else
|
||||
message="Installing ${item}…"
|
||||
fi
|
||||
echo "$item $itemName"
|
||||
|
||||
#Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
|
||||
#echo "icon before check: $icon"
|
||||
if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
|
||||
#echo "icon looks to be web-link"
|
||||
if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
|
||||
echo "ERROR: Cannot download ${icon} link. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
|
||||
#echo "icon looks to be a file"
|
||||
if [[ ! -a "${icon}" ]]; then
|
||||
echo "ERROR: Cannot find icon file ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
else
|
||||
echo "ERROR: Cannot figure out icon ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
#echo "icon after first check: $icon"
|
||||
# If no icon defined we are trying to search for installed app icon
|
||||
if [[ "$icon" == "" ]]; then
|
||||
appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
|
||||
appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
|
||||
if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
|
||||
appIcon="${appIcon}.icns"
|
||||
fi
|
||||
icon="${appPath}/Contents/Resources/${appIcon}"
|
||||
#echo "Icon before file check: ${icon}"
|
||||
if [ ! -f "${icon}" ]; then
|
||||
# Using LOGO variable to show logo in swiftDialog
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
icon="${LOGO_PATH}"
|
||||
fi
|
||||
fi
|
||||
echo "LOGO: $LOGO"
|
||||
echo "icon: ${icon}"
|
||||
|
||||
# display first screen
|
||||
open -a "$dialogApp" --args \
|
||||
--title none \
|
||||
--icon "$icon" \
|
||||
--message "$message" \
|
||||
--mini \
|
||||
--progress 100 \
|
||||
--position bottomright \
|
||||
--movable \
|
||||
--commandfile "$dialog_command_file"
|
||||
|
||||
# give everything a moment to catch up
|
||||
sleep 0.1
|
||||
fi
|
||||
|
||||
# Install software using Installomator with valuesfromarguments
|
||||
cmdOutput="$(${destFile} valuesfromarguments LOGO=$LOGO \
|
||||
name=\"${name}\" \
|
||||
type=${type} \
|
||||
packageID=${packageID} \
|
||||
downloadURL=\"$downloadURL\" \
|
||||
appNewVersion=${appNewVersion} \
|
||||
versionKey=${versionKey} \
|
||||
expectedTeamID=${expectedTeamID} \
|
||||
${installomatorOptions} ${installomatorNotify} || true)"
|
||||
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
|
||||
# Mark: dockutil stuff
|
||||
if [[ $addToDock -eq 1 ]]; then
|
||||
dialogUpdate "progresstext: Adding to Dock"
|
||||
if [[ ! -d $dockutil ]]; then
|
||||
echo "Cannot find dockutil at $dockutil, trying installation"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
echo "Adding to Dock"
|
||||
$dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
|
||||
sleep 1
|
||||
else
|
||||
echo "Not adding to Dock."
|
||||
fi
|
||||
|
||||
# Mark: Ending
|
||||
if [[ $installomatorVersion -ge 10 && $(sw_vers -buildVersion | cut -c1-2) -ge 20 ]]; then
|
||||
# close and quit dialog
|
||||
dialogUpdate "progress: complete"
|
||||
dialogUpdate "progresstext: Done"
|
||||
|
||||
# pause a moment
|
||||
sleep 0.5
|
||||
|
||||
dialogUpdate "quit:"
|
||||
|
||||
# let everything catch up
|
||||
sleep 0.5
|
||||
|
||||
# just to be safe
|
||||
#killall "Dialog" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
300
MDM/App-install SS with swiftDialog and dockutil/App VFA SS.sh
Executable file
300
MDM/App-install SS with swiftDialog and dockutil/App VFA SS.sh
Executable file
@@ -0,0 +1,300 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator with Dialog showing progress (and posibility of adding to the Dock)
|
||||
# Installation of software using `valuesfromarguments` to install a custom software using Installomator
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
# Have the label been submittet in a PR for Installomator?
|
||||
# What version of Installomator is it expected to be included in?
|
||||
# Version 10.0
|
||||
|
||||
item="clickshare" # enter the software to install (if it has a label in future version of Installomator)
|
||||
|
||||
# Variables for label
|
||||
name="ClickShare" # If spaces in the name, fill out "${name}" in Installomator-call below, circa line 249. Spaces should be escaped in that line.
|
||||
type="appInDmgInZip"
|
||||
packageID=""
|
||||
downloadURL="https://www.barco.com$( curl -fs "https://www.barco.com/en/clickshare/app" | grep -A6 -i "macos" | grep -i "FileNumber" | tr '"' "\n" | grep -i "FileNumber" )"
|
||||
appNewVersion="$(eval "$( echo $downloadURL | sed -E 's/.*(MajorVersion.*BuildVersion=[0-9]*).*/\1/' | sed 's/&//g' )" ; ((MajorVersion++)) ; ((MajorVersion--)); ((MinorVersion++)) ; ((MinorVersion--)); ((PatchVersion++)) ; ((PatchVersion--)); ((BuildVersion++)) ; ((BuildVersion--)); echo "${MajorVersion}.${MinorVersion}.${PatchVersion}-b${BuildVersion}")"
|
||||
expectedTeamID="P6CDJZR997"
|
||||
|
||||
# Dialog icon
|
||||
icon=""
|
||||
# icon should be a file system path or an URL to an online PNG.
|
||||
# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
|
||||
|
||||
# dockutil variables
|
||||
addToDock="1" # with dockutil after installation (0 if not)
|
||||
appPath="/Applications/$name.app"
|
||||
|
||||
# Other variables
|
||||
dialog_command_file="/var/tmp/dialog.log"
|
||||
dialogApp="/Library/Application Support/Dialog/Dialog.app"
|
||||
dockutil="/usr/local/bin/dockutil"
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill out the label variables above, and those will be included in the Installomator call, circa on line 248
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 10.0.3 : A bit more logging on succes, and change in ending Dialog part.
|
||||
# v. 10.0.2 : Improved icon checks and failovers
|
||||
# v. 10.0.1 : Improved appIcon handling. Can add the app to Dock using dockutil
|
||||
# v. 10.0 : Integration with Dialog and Installomator v. 10
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
if [[ -z "$item" ]]; then
|
||||
item="$name"
|
||||
fi
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand="$1"
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> "$dialog_command_file"
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
checkCmdOutput () {
|
||||
local checkOutput="$1"
|
||||
exitStatus="$( echo "${checkOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${checkOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$checkOutput"
|
||||
#errorOutput="$( echo "${checkOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
#echo "$checkOutput"
|
||||
}
|
||||
|
||||
# Check the currently logged in user
|
||||
currentUser=$(stat -f "%Su" /dev/console)
|
||||
if [[ -z "$currentUser" ]] || [[ "$currentUser" = "loginwindow" ]] || [[ "$currentUser" = "_mbsetupuser" ]] || [[ "$currentUser" = "root" ]]; then
|
||||
echo "ERROR. Logged in user is $currentUser! Cannot proceed."
|
||||
exit 97
|
||||
fi
|
||||
# Get the current user's UID for dockutil
|
||||
uid=$(id -u "$currentUser")
|
||||
# Find the home folder of the user
|
||||
userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Mark: Installation begins
|
||||
installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
|
||||
|
||||
if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion | cut -c1-2) -lt 20 ]]; then
|
||||
echo "Skipping swiftDialog UI, using notifications."
|
||||
#echo "Installomator should be at least version 10 to support swiftDialog. Installed version $installomatorVersion."
|
||||
#echo "And macOS 11 Big Sur (build 20A) is required for swiftDialog. Installed build $(sw_vers -buildVersion)."
|
||||
installomatorNotify="NOTIFY=all"
|
||||
else
|
||||
installomatorNotify="NOTIFY=silent"
|
||||
# check for Swift Dialog
|
||||
if [[ ! -d $dialogApp ]]; then
|
||||
echo "Cannot find dialog at $dialogApp"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
|
||||
# Configure and display swiftDialog
|
||||
itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
|
||||
if [[ "$itemName" != "#" ]]; then
|
||||
message="Installing ${itemName}…"
|
||||
else
|
||||
message="Installing ${item}…"
|
||||
fi
|
||||
echo "$item $itemName"
|
||||
|
||||
#Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
|
||||
#echo "icon before check: $icon"
|
||||
if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
|
||||
#echo "icon looks to be web-link"
|
||||
if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
|
||||
echo "ERROR: Cannot download ${icon} link. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
|
||||
#echo "icon looks to be a file"
|
||||
if [[ ! -a "${icon}" ]]; then
|
||||
echo "ERROR: Cannot find icon file ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
else
|
||||
echo "ERROR: Cannot figure out icon ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
#echo "icon after first check: $icon"
|
||||
# If no icon defined we are trying to search for installed app icon
|
||||
if [[ "$icon" == "" ]]; then
|
||||
appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
|
||||
appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
|
||||
if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
|
||||
appIcon="${appIcon}.icns"
|
||||
fi
|
||||
icon="${appPath}/Contents/Resources/${appIcon}"
|
||||
#echo "Icon before file check: ${icon}"
|
||||
if [ ! -f "${icon}" ]; then
|
||||
# Using LOGO variable to show logo in swiftDialog
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
icon="${LOGO_PATH}"
|
||||
fi
|
||||
fi
|
||||
echo "LOGO: $LOGO"
|
||||
echo "icon: ${icon}"
|
||||
|
||||
# display first screen
|
||||
open -a "$dialogApp" --args \
|
||||
--title none \
|
||||
--icon "$icon" \
|
||||
--message "$message" \
|
||||
--mini \
|
||||
--progress 100 \
|
||||
--position bottomright \
|
||||
--movable \
|
||||
--commandfile "$dialog_command_file"
|
||||
|
||||
# give everything a moment to catch up
|
||||
sleep 0.1
|
||||
fi
|
||||
|
||||
# Install software using Installomator with valuesfromarguments
|
||||
cmdOutput="$(${destFile} valuesfromarguments LOGO=$LOGO \
|
||||
name=\"${name}\" \
|
||||
type=${type} \
|
||||
packageID=${packageID} \
|
||||
downloadURL=\"$downloadURL\" \
|
||||
appNewVersion=${appNewVersion} \
|
||||
versionKey=${versionKey} \
|
||||
expectedTeamID=${expectedTeamID} \
|
||||
${installomatorOptions} ${installomatorNotify} || true)"
|
||||
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
|
||||
# Mark: dockutil stuff
|
||||
if [[ $addToDock -eq 1 ]]; then
|
||||
dialogUpdate "progresstext: Adding to Dock"
|
||||
if [[ ! -d $dockutil ]]; then
|
||||
echo "Cannot find dockutil at $dockutil, trying installation"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
echo "Adding to Dock"
|
||||
$dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
|
||||
sleep 1
|
||||
else
|
||||
echo "Not adding to Dock."
|
||||
fi
|
||||
|
||||
# Mark: Ending
|
||||
if [[ $installomatorVersion -ge 10 && $(sw_vers -buildVersion | cut -c1-2) -ge 20 ]]; then
|
||||
# close and quit dialog
|
||||
dialogUpdate "progress: complete"
|
||||
dialogUpdate "progresstext: Done"
|
||||
|
||||
# pause a moment
|
||||
sleep 0.5
|
||||
|
||||
dialogUpdate "quit:"
|
||||
|
||||
# let everything catch up
|
||||
sleep 0.5
|
||||
|
||||
# just to be safe
|
||||
#killall "Dialog" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
275
MDM/App-install SS with swiftDialog and dockutil/App browser-security SS.sh
Executable file
275
MDM/App-install SS with swiftDialog and dockutil/App browser-security SS.sh
Executable file
@@ -0,0 +1,275 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator with Dialog showing progress (and posibility of adding to the Dock)
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="" # enter the software to install
|
||||
# Examples: brave, duckduckgo, firefoxpkg, googlechromepkg, microsoftedge, opera
|
||||
|
||||
# Dialog icon
|
||||
icon=""
|
||||
# icon should be a file system path or an URL to an online PNG.
|
||||
# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
|
||||
|
||||
# dockutil variables
|
||||
addToDock="1" # with dockutil after installation (0 if not)
|
||||
appPath="/Applications/Firefox.app"
|
||||
|
||||
# Other variables
|
||||
dialog_command_file="/var/tmp/dialog.log"
|
||||
dialogApp="/Library/Application Support/Dialog/Dialog.app"
|
||||
dockutil="/usr/local/bin/dockutil"
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=tell_user_then_quit DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "item" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 10.0.3 : A bit more logging on succes, and change in ending Dialog part.
|
||||
# v. 10.0.2 : Improved icon checks and failovers
|
||||
# v. 10.0.1 : Improved appIcon handling. Can add the app to Dock using dockutil
|
||||
# v. 10.0 : Integration with Dialog and Installomator v. 10
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand="$1"
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> "$dialog_command_file"
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
checkCmdOutput () {
|
||||
local checkOutput="$1"
|
||||
exitStatus="$( echo "${checkOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${checkOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$checkOutput"
|
||||
#errorOutput="$( echo "${checkOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
#echo "$checkOutput"
|
||||
}
|
||||
|
||||
# Check the currently logged in user
|
||||
currentUser=$(stat -f "%Su" /dev/console)
|
||||
if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
|
||||
echo "ERROR. Logged in user is $currentUser! Cannot proceed."
|
||||
exit 97
|
||||
fi
|
||||
# Get the current user's UID for dockutil
|
||||
uid=$(id -u "$currentUser")
|
||||
# Find the home folder of the user
|
||||
userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Mark: Installation begins
|
||||
installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
|
||||
|
||||
if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion | cut -c1-2) -lt 20 ]]; then
|
||||
echo "Skipping swiftDialog UI, using notifications."
|
||||
#echo "Installomator should be at least version 10 to support swiftDialog. Installed version $installomatorVersion."
|
||||
#echo "And macOS 11 Big Sur (build 20A) is required for swiftDialog. Installed build $(sw_vers -buildVersion)."
|
||||
installomatorNotify="NOTIFY=all"
|
||||
else
|
||||
installomatorNotify="NOTIFY=silent"
|
||||
# check for Swift Dialog
|
||||
if [[ ! -d $dialogApp ]]; then
|
||||
echo "Cannot find dialog at $dialogApp"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
|
||||
# Configure and display swiftDialog
|
||||
itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
|
||||
if [[ "$itemName" != "#" ]]; then
|
||||
message="Installing ${itemName}…"
|
||||
else
|
||||
message="Installing ${item}…"
|
||||
fi
|
||||
echo "$item $itemName"
|
||||
|
||||
#Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
|
||||
#echo "icon before check: $icon"
|
||||
if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
|
||||
#echo "icon looks to be web-link"
|
||||
if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
|
||||
echo "ERROR: Cannot download ${icon} link. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
|
||||
#echo "icon looks to be a file"
|
||||
if [[ ! -a "${icon}" ]]; then
|
||||
echo "ERROR: Cannot find icon file ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
else
|
||||
echo "ERROR: Cannot figure out icon ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
#echo "icon after first check: $icon"
|
||||
# If no icon defined we are trying to search for installed app icon
|
||||
if [[ "$icon" == "" ]]; then
|
||||
appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
|
||||
appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
|
||||
if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
|
||||
appIcon="${appIcon}.icns"
|
||||
fi
|
||||
icon="${appPath}/Contents/Resources/${appIcon}"
|
||||
#echo "Icon before file check: ${icon}"
|
||||
if [ ! -f "${icon}" ]; then
|
||||
# Using LOGO variable to show logo in swiftDialog
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
icon="${LOGO_PATH}"
|
||||
fi
|
||||
fi
|
||||
echo "LOGO: $LOGO"
|
||||
echo "icon: ${icon}"
|
||||
|
||||
# display first screen
|
||||
open -a "$dialogApp" --args \
|
||||
--title none \
|
||||
--icon "$icon" \
|
||||
--message "$message" \
|
||||
--mini \
|
||||
--progress 100 \
|
||||
--position bottomright \
|
||||
--movable \
|
||||
--commandfile "$dialog_command_file"
|
||||
|
||||
# give everything a moment to catch up
|
||||
sleep 0.1
|
||||
fi
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} ${installomatorNotify} || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
|
||||
# Mark: dockutil stuff
|
||||
if [[ $addToDock -eq 1 ]]; then
|
||||
dialogUpdate "progresstext: Adding to Dock"
|
||||
if [[ ! -d $dockutil ]]; then
|
||||
echo "Cannot find dockutil at $dockutil, trying installation"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
echo "Adding to Dock"
|
||||
$dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
|
||||
sleep 1
|
||||
else
|
||||
echo "Not adding to Dock."
|
||||
fi
|
||||
|
||||
# Mark: Ending
|
||||
if [[ $installomatorVersion -ge 10 && $(sw_vers -buildVersion | cut -c1-2) -ge 20 ]]; then
|
||||
# close and quit dialog
|
||||
dialogUpdate "progress: complete"
|
||||
dialogUpdate "progresstext: Done"
|
||||
|
||||
# pause a moment
|
||||
sleep 0.5
|
||||
|
||||
dialogUpdate "quit:"
|
||||
|
||||
# let everything catch up
|
||||
sleep 0.5
|
||||
|
||||
# just to be safe
|
||||
#killall "Dialog" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
@@ -0,0 +1,278 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator with Dialog showing progress (and posibility of adding to the Dock)
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="microsoftoffice365" # enter the software to install
|
||||
# Examples: microsoftofficebusinesspro, microsoftoffice365
|
||||
|
||||
# Dialog icon
|
||||
icon=""
|
||||
# icon should be a file system path or an URL to an online PNG.
|
||||
# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
|
||||
|
||||
# dockutil variables
|
||||
addToDock="1" # with dockutil after installation (0 if not)
|
||||
appPaths=("/Applications/Microsoft Outlook.app" "/Applications/Microsoft Word.app" "/Applications/Microsoft Excel.app" "/Applications/Microsoft PowerPoint.app" "/Applications/Microsoft OneNote.app")
|
||||
|
||||
# Other variables
|
||||
dialog_command_file="/var/tmp/dialog.log"
|
||||
dialogApp="/Library/Application Support/Dialog/Dialog.app"
|
||||
dockutil="/usr/local/bin/dockutil"
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "item" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 10.0.3 : A bit more logging on succes, and change in ending Dialog part.
|
||||
# v. 10.0.2 : Improved icon checks and failovers
|
||||
# v. 10.0.1 : Improved appIcon handling. Can add the app to Dock using dockutil
|
||||
# v. 10.0 : Integration with Dialog and Installomator v. 10
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand="$1"
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> "$dialog_command_file"
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
checkCmdOutput () {
|
||||
local checkOutput="$1"
|
||||
exitStatus="$( echo "${checkOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${checkOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$checkOutput"
|
||||
#errorOutput="$( echo "${checkOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
#echo "$checkOutput"
|
||||
}
|
||||
|
||||
# Check the currently logged in user
|
||||
currentUser=$(stat -f "%Su" /dev/console)
|
||||
if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
|
||||
echo "ERROR. Logged in user is $currentUser! Cannot proceed."
|
||||
exit 97
|
||||
fi
|
||||
# Get the current user's UID for dockutil
|
||||
uid=$(id -u "$currentUser")
|
||||
# Find the home folder of the user
|
||||
userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Mark: Installation begins
|
||||
installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
|
||||
|
||||
if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion | cut -c1-2) -lt 20 ]]; then
|
||||
echo "Skipping swiftDialog UI, using notifications."
|
||||
#echo "Installomator should be at least version 10 to support swiftDialog. Installed version $installomatorVersion."
|
||||
#echo "And macOS 11 Big Sur (build 20A) is required for swiftDialog. Installed build $(sw_vers -buildVersion)."
|
||||
installomatorNotify="NOTIFY=all"
|
||||
else
|
||||
installomatorNotify="NOTIFY=silent"
|
||||
# check for Swift Dialog
|
||||
if [[ ! -d $dialogApp ]]; then
|
||||
echo "Cannot find dialog at $dialogApp"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
|
||||
# Configure and display swiftDialog
|
||||
itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
|
||||
if [[ "$itemName" != "#" ]]; then
|
||||
message="Installing ${itemName}…"
|
||||
else
|
||||
message="Installing ${item}…"
|
||||
fi
|
||||
echo "$item $itemName"
|
||||
|
||||
#Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
|
||||
#echo "icon before check: $icon"
|
||||
if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
|
||||
#echo "icon looks to be web-link"
|
||||
if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
|
||||
echo "ERROR: Cannot download ${icon} link. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
|
||||
#echo "icon looks to be a file"
|
||||
if [[ ! -a "${icon}" ]]; then
|
||||
echo "ERROR: Cannot find icon file ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
else
|
||||
echo "ERROR: Cannot figure out icon ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
#echo "icon after first check: $icon"
|
||||
# If no icon defined we are trying to search for installed app icon
|
||||
if [[ "$icon" == "" ]]; then
|
||||
appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
|
||||
appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
|
||||
if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
|
||||
appIcon="${appIcon}.icns"
|
||||
fi
|
||||
icon="${appPath}/Contents/Resources/${appIcon}"
|
||||
#echo "Icon before file check: ${icon}"
|
||||
if [ ! -f "${icon}" ]; then
|
||||
# Using LOGO variable to show logo in swiftDialog
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
icon="${LOGO_PATH}"
|
||||
fi
|
||||
fi
|
||||
echo "LOGO: $LOGO"
|
||||
echo "icon: ${icon}"
|
||||
|
||||
# display first screen
|
||||
open -a "$dialogApp" --args \
|
||||
--title none \
|
||||
--icon "$icon" \
|
||||
--message "$message" \
|
||||
--mini \
|
||||
--progress 100 \
|
||||
--position bottomright \
|
||||
--movable \
|
||||
--commandfile "$dialog_command_file"
|
||||
|
||||
# give everything a moment to catch up
|
||||
sleep 0.1
|
||||
fi
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} ${installomatorNotify} || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
|
||||
# Mark: dockutil stuff
|
||||
if [[ $addToDock -eq 1 ]]; then
|
||||
dialogUpdate "progresstext: Adding to Dock"
|
||||
if [[ ! -d $dockutil ]]; then
|
||||
echo "Cannot find dockutil at $dockutil, trying installation"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
echo "Adding to Dock"
|
||||
for appPath in "${appPaths[@]}"; do
|
||||
$dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" --no-restart || true
|
||||
done
|
||||
$dockutil --add "/AppThatDoesNotExistAnywhereOnDiskButMakingDockutilRestartTheDock" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
|
||||
sleep 1
|
||||
else
|
||||
echo "Not adding to Dock."
|
||||
fi
|
||||
|
||||
# Mark: Ending
|
||||
iif [[ $installomatorVersion -ge 10 && $(sw_vers -buildVersion | cut -c1-2) -ge 20 ]]; then
|
||||
# close and quit dialog
|
||||
dialogUpdate "progress: complete"
|
||||
dialogUpdate "progresstext: Done"
|
||||
|
||||
# pause a moment
|
||||
sleep 0.5
|
||||
|
||||
dialogUpdate "quit:"
|
||||
|
||||
# let everything catch up
|
||||
sleep 0.5
|
||||
|
||||
# just to be safe
|
||||
#killall "Dialog" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
@@ -0,0 +1,272 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator with Dialog showing progress (and posibility of adding to the Dock)
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="" # enter the software to install
|
||||
# Examples: adobecreativeclouddesktop, canva, cyberduck, handbrake, inkscape, textmate, vlc
|
||||
|
||||
# Dialog icon
|
||||
icon=""
|
||||
# icon should be a file system path or an URL to an online PNG, so beginning with either “/” or “http”.
|
||||
# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
|
||||
|
||||
# dockutil variables
|
||||
addToDock="0" # with dockutil after installation (0 if not)
|
||||
appPath="/Applications/Cyberduck.app"
|
||||
|
||||
# Other variables
|
||||
dialog_command_file="/var/tmp/dialog.log"
|
||||
dialogApp="/Library/Application Support/Dialog/Dialog.app"
|
||||
dockutil="/usr/local/bin/dockutil"
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "item" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 10.0.3 : A bit more logging on succes, and change in ending Dialog part.
|
||||
# v. 10.0.2 : Improved icon checks and failovers
|
||||
# v. 10.0.1 : Improved appIcon handling. Can add the app to Dock using dockutil
|
||||
# v. 10.0 : Integration with Dialog and Installomator v. 10
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand="$1"
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> "$dialog_command_file"
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
checkCmdOutput () {
|
||||
local checkOutput="$1"
|
||||
exitStatus="$( echo "${checkOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${checkOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$checkOutput"
|
||||
#errorOutput="$( echo "${checkOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
#echo "$checkOutput"
|
||||
}
|
||||
|
||||
# Check the currently logged in user
|
||||
currentUser=$(stat -f "%Su" /dev/console)
|
||||
if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
|
||||
echo "ERROR. Logged in user is $currentUser! Cannot proceed."
|
||||
exit 97
|
||||
fi
|
||||
# Get the current user's UID for dockutil
|
||||
uid=$(id -u "$currentUser")
|
||||
# Find the home folder of the user
|
||||
userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Mark: Installation begins
|
||||
installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
|
||||
|
||||
if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion | cut -c1-2) -lt 20 ]]; then
|
||||
echo "Skipping swiftDialog UI, using notifications."
|
||||
#echo "Installomator should be at least version 10 to support swiftDialog. Installed version $installomatorVersion."
|
||||
#echo "And macOS 11 Big Sur (build 20A) is required for swiftDialog. Installed build $(sw_vers -buildVersion)."
|
||||
installomatorNotify="NOTIFY=all"
|
||||
else
|
||||
installomatorNotify="NOTIFY=silent"
|
||||
# check for Swift Dialog
|
||||
if [[ ! -d $dialogApp ]]; then
|
||||
echo "Cannot find dialog at $dialogApp"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
|
||||
# Configure and display swiftDialog
|
||||
itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
|
||||
if [[ "$itemName" != "#" ]]; then
|
||||
message="Installing ${itemName}…"
|
||||
else
|
||||
message="Installing ${item}…"
|
||||
fi
|
||||
echo "$item $itemName"
|
||||
|
||||
#Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
|
||||
#echo "icon before check: $icon"
|
||||
if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
|
||||
#echo "icon looks to be web-link"
|
||||
if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
|
||||
echo "ERROR: Cannot download ${icon} link. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
|
||||
#echo "icon looks to be a file"
|
||||
if [[ ! -a "${icon}" ]]; then
|
||||
echo "ERROR: Cannot find icon file ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
else
|
||||
echo "ERROR: Cannot figure out icon ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
#echo "icon after first check: $icon"
|
||||
# If no icon defined we are trying to search for installed app icon
|
||||
if [[ "$icon" == "" ]]; then
|
||||
appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
|
||||
appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
|
||||
if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
|
||||
appIcon="${appIcon}.icns"
|
||||
fi
|
||||
icon="${appPath}/Contents/Resources/${appIcon}"
|
||||
#echo "Icon before file check: ${icon}"
|
||||
if [ ! -f "${icon}" ]; then
|
||||
# Using LOGO variable to show logo in swiftDialog
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
icon="${LOGO_PATH}"
|
||||
fi
|
||||
fi
|
||||
echo "LOGO: $LOGO"
|
||||
echo "icon: ${icon}"
|
||||
|
||||
# display first screen
|
||||
open -a "$dialogApp" --args \
|
||||
--title none \
|
||||
--icon "$icon" \
|
||||
--message "$message" \
|
||||
--mini \
|
||||
--progress 100 \
|
||||
--position bottomright \
|
||||
--movable \
|
||||
--commandfile "$dialog_command_file"
|
||||
|
||||
# give everything a moment to catch up
|
||||
sleep 0.1
|
||||
fi
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} ${installomatorNotify} || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
|
||||
# Mark: dockutil stuff
|
||||
if [[ $addToDock -eq 1 ]]; then
|
||||
dialogUpdate "progresstext: Adding to Dock"
|
||||
if [[ ! -d $dockutil ]]; then
|
||||
echo "Cannot find dockutil at $dockutil, trying installation"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
echo "Adding to Dock"
|
||||
$dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
|
||||
sleep 1
|
||||
else
|
||||
echo "Not adding to Dock."
|
||||
fi
|
||||
|
||||
# Mark: Ending
|
||||
if [[ $installomatorVersion -ge 10 && $(sw_vers -buildVersion | cut -c1-2) -ge 20 ]]; then
|
||||
# close and quit dialog
|
||||
dialogUpdate "progress: complete"
|
||||
dialogUpdate "progresstext: Done"
|
||||
|
||||
# pause a moment
|
||||
sleep 0.5
|
||||
|
||||
dialogUpdate "quit:"
|
||||
|
||||
# let everything catch up
|
||||
sleep 0.5
|
||||
|
||||
# just to be safe
|
||||
#killall "Dialog" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
@@ -0,0 +1,275 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="" # enter the software to install
|
||||
# Examples: applenyfonts, applesfarabic, applesfcompact, applesfmono, applesfpro, applesfsymbols, desktoppr, dialog, dockutil, knockknock, lulu, nomad, nudge, shield, supportapp, wordservice, xcreds, xink
|
||||
|
||||
# Dialog icon
|
||||
icon=""
|
||||
# icon should be a file system path or an URL to an online PNG.
|
||||
# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
|
||||
|
||||
# dockutil variables
|
||||
addToDock="1" # with dockutil after installation (0 if not)
|
||||
appPath="/Applications/Xink.app"
|
||||
|
||||
# Other variables
|
||||
dialog_command_file="/var/tmp/dialog.log"
|
||||
dialogApp="/Library/Application Support/Dialog/Dialog.app"
|
||||
dockutil="/usr/local/bin/dockutil"
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=ignore DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "item" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 10.0.3 : A bit more logging on succes, and change in ending Dialog part.
|
||||
# v. 10.0.2 : Improved icon checks and failovers
|
||||
# v. 10.0.1 : Can add the app to Dock using dockutil
|
||||
# v. 10.0 : Integration with Dialog and Installomator v. 10
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand="$1"
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> "$dialog_command_file"
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
checkCmdOutput () {
|
||||
local checkOutput="$1"
|
||||
exitStatus="$( echo "${checkOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${checkOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$checkOutput"
|
||||
#errorOutput="$( echo "${checkOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
#echo "$checkOutput"
|
||||
}
|
||||
|
||||
# Check the currently logged in user
|
||||
currentUser=$(stat -f "%Su" /dev/console)
|
||||
if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
|
||||
echo "ERROR. Logged in user is $currentUser! Cannot proceed."
|
||||
exit 97
|
||||
fi
|
||||
# Get the current user's UID for dockutil
|
||||
uid=$(id -u "$currentUser")
|
||||
# Find the home folder of the user
|
||||
userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Mark: Installation begins
|
||||
installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
|
||||
|
||||
if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion | cut -c1-2) -lt 20 ]]; then
|
||||
echo "Skipping swiftDialog UI, using notifications."
|
||||
#echo "Installomator should be at least version 10 to support swiftDialog. Installed version $installomatorVersion."
|
||||
#echo "And macOS 11 Big Sur (build 20A) is required for swiftDialog. Installed build $(sw_vers -buildVersion)."
|
||||
installomatorNotify="NOTIFY=all"
|
||||
else
|
||||
installomatorNotify="NOTIFY=silent"
|
||||
# check for Swift Dialog
|
||||
if [[ ! -d $dialogApp ]]; then
|
||||
echo "Cannot find dialog at $dialogApp"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
|
||||
# Configure and display swiftDialog
|
||||
itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
|
||||
if [[ "$itemName" != "#" ]]; then
|
||||
message="Installing ${itemName}…"
|
||||
else
|
||||
message="Installing ${item}…"
|
||||
fi
|
||||
echo "$item $itemName"
|
||||
|
||||
#Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
|
||||
#echo "icon before check: $icon"
|
||||
if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
|
||||
#echo "icon looks to be web-link"
|
||||
if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
|
||||
echo "ERROR: Cannot download ${icon} link. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
|
||||
#echo "icon looks to be a file"
|
||||
if [[ ! -a "${icon}" ]]; then
|
||||
echo "ERROR: Cannot find icon file ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
else
|
||||
echo "ERROR: Cannot figure out icon ${icon}. Reset icon."
|
||||
icon=""
|
||||
fi
|
||||
#echo "icon after first check: $icon"
|
||||
# If no icon defined we are trying to search for installed app icon
|
||||
if [[ "$icon" == "" ]]; then
|
||||
appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
|
||||
appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
|
||||
if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
|
||||
appIcon="${appIcon}.icns"
|
||||
fi
|
||||
icon="${appPath}/Contents/Resources/${appIcon}"
|
||||
#echo "Icon before file check: ${icon}"
|
||||
if [ ! -f "${icon}" ]; then
|
||||
# Using LOGO variable to show logo in swiftDialog
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
icon="${LOGO_PATH}"
|
||||
fi
|
||||
fi
|
||||
echo "LOGO: $LOGO"
|
||||
echo "icon: ${icon}"
|
||||
|
||||
# display first screen
|
||||
open -a "$dialogApp" --args \
|
||||
--title none \
|
||||
--icon "$icon" \
|
||||
--message "$message" \
|
||||
--mini \
|
||||
--progress 100 \
|
||||
--position bottomright \
|
||||
--movable \
|
||||
--commandfile "$dialog_command_file"
|
||||
|
||||
# give everything a moment to catch up
|
||||
sleep 0.1
|
||||
fi
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} ${installomatorNotify} || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
|
||||
# Mark: dockutil stuff
|
||||
if [[ $addToDock -eq 1 ]]; then
|
||||
dialogUpdate "progresstext: Adding to Dock"
|
||||
if [[ ! -d $dockutil ]]; then
|
||||
echo "Cannot find dockutil at $dockutil, trying installation"
|
||||
# Install using Installlomator
|
||||
cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
|
||||
checkCmdOutput "${cmdOutput}"
|
||||
fi
|
||||
echo "Adding to Dock"
|
||||
$dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
|
||||
sleep 1
|
||||
else
|
||||
echo "Not adding to Dock."
|
||||
fi
|
||||
|
||||
# Mark: Ending
|
||||
if [[ $installomatorVersion -ge 10 && $(sw_vers -buildVersion | cut -c1-2) -ge 20 ]]; then
|
||||
# close and quit dialog
|
||||
dialogUpdate "progress: complete"
|
||||
dialogUpdate "progresstext: Done"
|
||||
|
||||
# pause a moment
|
||||
sleep 0.5
|
||||
|
||||
dialogUpdate "quit:"
|
||||
|
||||
# let everything catch up
|
||||
sleep 0.5
|
||||
|
||||
# just to be safe
|
||||
#killall "Dialog" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
103
MDM/App-install/App VFA.sh
Executable file
103
MDM/App-install/App VFA.sh
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator
|
||||
# Installation of software using valuesfromarguments to install a custom software using Installomator
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
# Have the label been submittet in a PR for Installomator?
|
||||
# What version of Installomator is it expected to be included in?
|
||||
# Version 10
|
||||
|
||||
item="" # enter the software to install (if it has a label in future version of Installomator)
|
||||
|
||||
# Variables for label
|
||||
name="ClickShare" # Spaces in the name will not work
|
||||
type="appInDmgInZip"
|
||||
packageID=""
|
||||
downloadURL="https://www.barco.com$( curl -fs "https://www.barco.com/en/clickshare/app" | grep -A6 -i "macos" | grep -i "FileNumber" | tr '"' "\n" | grep -i "FileNumber" )"
|
||||
appNewVersion="$(eval "$( echo $downloadURL | sed -E 's/.*(MajorVersion.*BuildVersion=[0-9]*).*/\1/' | sed 's/&//g' )" ; ((MajorVersion++)) ; ((MajorVersion--)); ((MinorVersion++)) ; ((MinorVersion--)); ((PatchVersion++)) ; ((PatchVersion--)); ((BuildVersion++)) ; ((BuildVersion--)); echo "${MajorVersion}.${MinorVersion}.${PatchVersion}-b${BuildVersion}")"
|
||||
versionKey=""
|
||||
expectedTeamID="P6CDJZR997"
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user LOGGING=INFO NOTIFY=all" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "what" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 9.2.2 : A bit more logging on succes.
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $what"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Install software using Installomator with valuesfromarguments
|
||||
cmdOutput="$(${destFile} valuesfromarguments LOGO=$LOGO \
|
||||
name=\"${name}\" \
|
||||
type=${type} \
|
||||
packageID=${packageID} \
|
||||
downloadURL=\"$downloadURL\" \
|
||||
appNewVersion=${appNewVersion} \
|
||||
versionKey=${versionKey} \
|
||||
expectedTeamID=${expectedTeamID} \
|
||||
blockingProcesses=\"NONE\" \
|
||||
${installomatorOptions} || true)"
|
||||
|
||||
|
||||
# Check result
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${what} succesfully installed."
|
||||
selectedOutput="$( echo "${cmdOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${what}. Exit code ${exitStatus}"
|
||||
echo "$cmdOutput"
|
||||
#errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
80
MDM/App-install/App browser-security Auto-install.sh
Normal file
80
MDM/App-install/App browser-security Auto-install.sh
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="firefoxpkg" # enter the software to install
|
||||
# Examples: brave, duckduckgo, firefoxpkg, googlechromepkg, microsoftedge, opera
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=tell_user_then_quit" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "item" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 9.2.2 : A bit more logging on succes.
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
|
||||
|
||||
# Check result
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${cmdOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$cmdOutput"
|
||||
#errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
80
MDM/App-install/App browser-security SS.sh
Normal file
80
MDM/App-install/App browser-security SS.sh
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="" # enter the software to install
|
||||
# Examples: brave, duckduckgo, firefoxpkg, googlechromepkg, microsoftedge, opera
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=tell_user_then_quit NOTIFY=all" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "what" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 9.2.2 : A bit more logging on succes.
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $what"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${what} LOGO=$LOGO ${installomatorOptions} || true)"
|
||||
|
||||
# Check result
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${what} succesfully installed."
|
||||
selectedOutput="$( echo "${cmdOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${what}. Exit code ${exitStatus}"
|
||||
echo "$cmdOutput"
|
||||
#errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
80
MDM/App-install/App normal Auto-install.sh
Normal file
80
MDM/App-install/App normal Auto-install.sh
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="" # enter the software to install
|
||||
# Examples: adobecreativeclouddesktop, textmate, vlc
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=tell_user" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "item" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 9.2.2 : A bit more logging on succes.
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
|
||||
|
||||
# Check result
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${cmdOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$cmdOutput"
|
||||
#errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
81
MDM/App-install/App normal SS.sh
Normal file
81
MDM/App-install/App normal SS.sh
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="" # enter the software to install
|
||||
# Examples: adobecreativeclouddesktop, canva, cyberduck, handbrake, inkscape, textmate, vlc
|
||||
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user NOTIFY=all" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "item" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 9.2.2 : A bit more logging on succes.
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
|
||||
|
||||
# Check result
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${cmdOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$cmdOutput"
|
||||
#errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
80
MDM/App-install/App service Auto-install.sh
Normal file
80
MDM/App-install/App service Auto-install.sh
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installation using Installomator
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="dockutil" # enter the software to install
|
||||
# Examples: applenyfonts, applesfarabic, applesfcompact, applesfmono, applesfpro, applesfsymbols, desktoppr, dialog, dockutil, knockknock, lulu, nomad, nudge, shield, supportapp, wordservice, xcreds, xink
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=ignore NOTIFY=silent" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "item" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 9.2.2 : A bit more logging on succes.
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
|
||||
|
||||
# Check result
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${cmdOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$cmdOutput"
|
||||
#errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
93
MDM/App-update/App browser-security Auto-install.sh
Normal file
93
MDM/App-update/App browser-security Auto-install.sh
Normal file
@@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Update with Installomator if app exist
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="microsoftedge" # enter the software to install
|
||||
# Examples: brave, duckduckgo, firefoxpkg, googlechromepkg, microsoftedge, opera
|
||||
appPath="/Applications/Microsoft Edge.app"
|
||||
# Examples: Microsoft Edge.app, Brave Browser.app, DuckDuckGo.app, Google Chrome.app, Firefox.app, Opera.app
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=tell_user_then_quit" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "item" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 9.2.2 : A bit more logging on succes.
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
# Check if app is installed
|
||||
# We only want this to run if it's already installed
|
||||
if [ ! -e "${appPath}" ]; then
|
||||
echo "App not found here:"
|
||||
echo "${appPath}"
|
||||
echo "Exiting."
|
||||
exit 98
|
||||
fi
|
||||
echo "${appPath} Found!"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
|
||||
|
||||
# Check result
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${cmdOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$cmdOutput"
|
||||
#errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
|
||||
93
MDM/App-update/App normal Auto-install.sh
Normal file
93
MDM/App-update/App normal Auto-install.sh
Normal file
@@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Update with Installomator if app exist
|
||||
|
||||
LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
item="" # enter the software to install
|
||||
# Examples: cyberduck, handbrake, textmate, vlc
|
||||
appPath="/Applications/Cyberduck.app"
|
||||
# Examples: Cyberduck.app, Handbrake.app, Textmate.app, VLC.app
|
||||
|
||||
installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user" # Separated by space
|
||||
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
# To be used as a script sent out from a MDM.
|
||||
# Fill the variable "item" above with a label.
|
||||
# Script will run this label through Installomator.
|
||||
######################################################################
|
||||
# v. 9.2.2 : A bit more logging on succes.
|
||||
# v. 9.2.1 : Better logging handling and installomatorOptions fix.
|
||||
######################################################################
|
||||
|
||||
# Mark: Script
|
||||
# PATH declaration
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
echo "$(date +%F\ %T) [LOG-BEGIN] $item"
|
||||
|
||||
# Check if app is installed
|
||||
# We only want this to run if it's already installed
|
||||
if [ ! -e "${appPath}" ]; then
|
||||
echo "App not found here:"
|
||||
echo "${appPath}"
|
||||
echo "Exiting."
|
||||
exit 98
|
||||
fi
|
||||
echo "${appPath} Found!"
|
||||
|
||||
# Verify that Installomator has been installed
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [ ! -e "${destFile}" ]; then
|
||||
echo "Installomator not found here:"
|
||||
echo "${destFile}"
|
||||
echo "Exiting."
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid"
|
||||
pkill caffeinate
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Install software using Installomator
|
||||
cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
|
||||
|
||||
# Check result
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
echo "${item} succesfully installed."
|
||||
selectedOutput="$( echo "${cmdOutput}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)" || true )"
|
||||
echo "$selectedOutput"
|
||||
else
|
||||
echo "ERROR installing ${item}. Exit code ${exitStatus}"
|
||||
echo "$cmdOutput"
|
||||
#errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
#echo "$errorOutput"
|
||||
fi
|
||||
|
||||
echo "[$(DATE)][LOG-END]"
|
||||
|
||||
caffexit $exitStatus
|
||||
|
||||
19
MDM/Collect Installomator.log.sh
Normal file
19
MDM/Collect Installomator.log.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
# A small script to grab Installomator log from a client Mac.
|
||||
# Can be sent to the client so the result can be seen in MDM
|
||||
# Only uncomment the line below for the things you want to see.
|
||||
|
||||
logFile="/var/log/Installomator.log"
|
||||
|
||||
# Show latest 100 lines of the log
|
||||
tail -100 "${logFile}"
|
||||
|
||||
# Show latest 500 lines but filter to REQ|ERROR|WARN lines
|
||||
# Great overview of the log
|
||||
#tail -500 "${logFile}" | grep --binary-files=text -E ": (REQ|ERROR|WARN)"
|
||||
|
||||
# Show only one label
|
||||
# Great to see everything for a label that might fail or not working as expected
|
||||
label="valuesfromarguments"
|
||||
#cat "${logFile}" | grep --binary-files=text ": ${label}"
|
||||
361
MDM/Installomator 1st Auto-install DEPNotify.sh
Executable file
361
MDM/Installomator 1st Auto-install DEPNotify.sh
Executable file
@@ -0,0 +1,361 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installomator 1st installation with DEPNotify window (auto installation at enrollment)
|
||||
instance="" # Name of used instance
|
||||
|
||||
LOGO="" # "appstore", "jamf", "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
items=(dialog dockutil microsoftautoupdate supportapp applenyfonts applesfpro applesfmono applesfcompact xink zohoworkdrivetruesync textmate 1password7 wwdc theunarchiver keka microsoftedge microsoftteams microsoftonedrive microsoftoffice365)
|
||||
# Remember: dialog dockutil
|
||||
|
||||
installomatorOptions="NOTIFY=silent BLOCKING_PROCESS_ACTION=ignore INSTALL=force IGNORE_APP_STORE_APPS=yes LOGGING=REQ"
|
||||
|
||||
# DEPNotify display settings, change as desired
|
||||
title="Installing Apps and other software"
|
||||
message="Please wait while we download and install the needed software."
|
||||
endMessage="Installation complete! Please reboot to activate FileVault."
|
||||
errorMessage="A problem was encountered setting up this Mac. Please contact IT."
|
||||
|
||||
######################################################################
|
||||
# Installomator 1st DEPNotify
|
||||
#
|
||||
# Installation using Installomator showing progress with DEPNotify
|
||||
# Great stand-alone solution if installs are only done using Installomator.
|
||||
# No customization below…
|
||||
######################################################################
|
||||
# This script can be used to install software using Installomator.
|
||||
# Script will start DEPNotify to display a progress bar.
|
||||
# Progress bar moves between installations
|
||||
######################################################################
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
#
|
||||
# This script made by Søren Theilgaard
|
||||
# https://github.com/Theile
|
||||
# Twitter and MacAdmins Slack: @theilgaard
|
||||
#
|
||||
# Some functions and code from Installomator:
|
||||
# https://github.com/Installomator/Installomator
|
||||
#
|
||||
######################################################################
|
||||
scriptVersion="9.6"
|
||||
# v. 9.6 : 2022-11-15 : GitHub API call is first, only try alternative if that fails.
|
||||
# v. 9.5 : 2022-09-21 : change of GitHub download
|
||||
# v. 9.4 : 2022-09-14 : downloadURL can fall back on GitHub API
|
||||
# v. 9.3 : 2022-08-29 : installomatorOptions in quotes and ignore blocking processes. Improved installation with looping if it fails, so it can try again. Improved GitHub handling. ws1 support.
|
||||
# v. 9.2.2 : 2022-06-17 : installomatorOptions introduced. Check 1.1.1.1 for internet connection.
|
||||
# v. 9.2.1 : 2022-05-30 : Some changes to logging
|
||||
# v. 9.2 : 2022-05-19 : Built in installer for Installlomator, and display dialog if error happens. Now universal script for all supported MDMs based on LOGO variable.
|
||||
# v. 9.1 : 2022-04-13 : Using INSTALL=force in Label only, so Microsoft labels will not start updating
|
||||
# v. 9.0.1 : 2022-02-21 : LOGO=addigy, few more "true" lines, and errorOutput on error
|
||||
# v. 9.0.0 : 2022-02-14 : Updated for Inst. 9.0, Logging improved with printlog
|
||||
######################################################################
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# Check before running
|
||||
case $LOGO in
|
||||
addigy|microsoft)
|
||||
conditionFile="/var/db/.Installomator1stDone"
|
||||
# Addigy and Microsoft Endpoint Manager (Intune) need a check for a touched file
|
||||
if [ -e "$conditionFile" ]; then
|
||||
echo "$LOGO setup detected"
|
||||
echo "$conditionFile exists, so we exit."
|
||||
exit 0
|
||||
else
|
||||
echo "$conditionFile not found, so we continue…"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Mark: Constants, logging and caffeinate
|
||||
log_message="$instance: Installomator 1st with DEPNotify, v$scriptVersion"
|
||||
label="1st-v$scriptVersion"
|
||||
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
printlog(){
|
||||
timestamp=$(date +%F\ %T)
|
||||
if [[ "$(whoami)" == "root" ]]; then
|
||||
echo "$timestamp :: $label : $1" | tee -a $log_location
|
||||
else
|
||||
echo "$timestamp :: $label : $1"
|
||||
fi
|
||||
}
|
||||
printlog "[LOG-BEGIN] ${log_message}"
|
||||
|
||||
# Internet check
|
||||
if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
|
||||
printlog "ERROR. No internet connection, we cannot continue."
|
||||
exit 90
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid" || true
|
||||
pkill caffeinate || true
|
||||
printlog "[LOG-END] Status $1"
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Command-file to DEPNotify
|
||||
DEPNOTIFY_LOG="/var/tmp/depnotify.log"
|
||||
|
||||
# Counters
|
||||
errorCount=0
|
||||
countLabels=${#items[@]}
|
||||
printlog "Total installations: $countLabels"
|
||||
|
||||
# Using LOGO variable to specify MDM and shown logo
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
printlog "LOGO: $LOGO - LOGO_PATH: $LOGO_PATH"
|
||||
|
||||
# Mark: Functions
|
||||
printlog "depnotify_command function"
|
||||
echo "" > $DEPNOTIFY_LOG || true
|
||||
function depnotify_command(){
|
||||
printlog "DEPNotify-command: $1"
|
||||
echo "$1" >> $DEPNOTIFY_LOG || true
|
||||
}
|
||||
|
||||
printlog "startDEPNotify function"
|
||||
function startDEPNotify() {
|
||||
currentUser="$(stat -f "%Su" /dev/console)"
|
||||
currentUserID=$(id -u "$currentUser")
|
||||
launchctl asuser $currentUserID open -a "/Applications/Utilities/DEPNotify.app/Contents/MacOS/DEPNotify" --args -path "$DEPNOTIFY_LOG" || true # --args -fullScreen
|
||||
sleep 5
|
||||
depnotify_command "Command: KillCommandFile:"
|
||||
depnotify_command "Command: MainTitle: $title"
|
||||
depnotify_command "Command: Image: $LOGO_PATH"
|
||||
depnotify_command "Command: MainText: $message"
|
||||
depnotify_command "Command: Determinate: $countLabels"
|
||||
}
|
||||
|
||||
# Notify the user using AppleScript
|
||||
printlog "displayDialog function"
|
||||
function displayDialog(){
|
||||
currentUser="$(stat -f "%Su" /dev/console)"
|
||||
currentUserID=$(id -u "$currentUser")
|
||||
if [[ "$currentUser" != "" ]]; then
|
||||
launchctl asuser $currentUserID sudo -u $currentUser osascript -e "button returned of (display dialog \"$message\" buttons {\"OK\"} default button \"OK\" with icon POSIX file \"$LOGO_PATH\")" || true
|
||||
fi
|
||||
}
|
||||
|
||||
# Mark: Code
|
||||
name="Installomator"
|
||||
printlog "$name check for installation"
|
||||
# download URL, version and Expected Team ID
|
||||
# Method for GitHub pkg
|
||||
gitusername="Installomator"
|
||||
gitreponame="Installomator"
|
||||
#printlog "$gitusername $gitreponame"
|
||||
filetype="pkg"
|
||||
downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
|
||||
printlog "GitHub API failed, trying failover."
|
||||
#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
fi
|
||||
#printlog "$downloadURL"
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
|
||||
#printlog "$appNewVersion"
|
||||
expectedTeamID="JME5BW3F3R"
|
||||
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
currentInstalledVersion="$(${destFile} version 2>/dev/null || true)"
|
||||
printlog "${destFile} version: $currentInstalledVersion"
|
||||
if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
|
||||
printlog "$name not found or version not latest."
|
||||
printlog "${destFile}"
|
||||
printlog "Installing version ${appNewVersion} ..."
|
||||
# Create temporary working directory
|
||||
tmpDir="$(mktemp -d || true)"
|
||||
printlog "Created working directory '$tmpDir'"
|
||||
# Download the installer package
|
||||
printlog "Downloading $name package version $appNewVersion from: $downloadURL"
|
||||
installationCount=0
|
||||
exitCode=9
|
||||
while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
|
||||
curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
|
||||
curlDownloadStatus=$(echo $?)
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
printlog "error downloading $downloadURL, with status $curlDownloadStatus"
|
||||
printlog "${curlDownload}"
|
||||
exitCode=1
|
||||
else
|
||||
printlog "Download $name succes."
|
||||
# Verify the download
|
||||
teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
|
||||
printlog "Team ID for downloaded package: $teamID"
|
||||
# Install the package if Team ID validates
|
||||
if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
|
||||
printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
|
||||
pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
|
||||
pkgInstallStatus=$(echo $?)
|
||||
if [[ $pkgInstallStatus -ne 0 ]]; then
|
||||
printlog "ERROR. $name package installation failed."
|
||||
printlog "${pkgInstall}"
|
||||
exitCode=2
|
||||
else
|
||||
printlog "Installing $name package succes."
|
||||
exitCode=0
|
||||
fi
|
||||
else
|
||||
printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
|
||||
exitCode=3
|
||||
fi
|
||||
fi
|
||||
((installationCount++))
|
||||
printlog "$installationCount time(s), exitCode $exitCode"
|
||||
if [[ $installationCount -lt 3 ]]; then
|
||||
if [[ $exitCode -gt 0 ]]; then
|
||||
printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
|
||||
printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
|
||||
sleep 2
|
||||
fi
|
||||
else
|
||||
printlog "Download and install of $name succes."
|
||||
fi
|
||||
done
|
||||
# Remove the temporary working directory
|
||||
printlog "Deleting working directory '$tmpDir' and its contents."
|
||||
printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
|
||||
# Handle installation errors
|
||||
if [[ $exitCode != 0 ]]; then
|
||||
printlog "ERROR. Installation of $name failed. Aborting."
|
||||
caffexit $exitCode
|
||||
else
|
||||
printlog "$name version $appNewVersion installed!"
|
||||
fi
|
||||
else
|
||||
printlog "$name version $appNewVersion already found. Perfect!"
|
||||
fi
|
||||
|
||||
# Installing DEPNotify
|
||||
cmdOutput="$( ${destFile} depnotify LOGO=$LOGO NOTIFY=silent BLOCKING_PROCESS_ACTION=ignore LOGGING=WARN || true )"
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
printlog "DEPNotify install result: $exitStatus"
|
||||
|
||||
itemName=""
|
||||
errorLabels=""
|
||||
((countLabels++))
|
||||
((countLabels--))
|
||||
printlog "$countLabels labels to install"
|
||||
|
||||
startDEPNotify
|
||||
|
||||
for item in "${items[@]}"; do
|
||||
# Check if DEPNotify is running and try open it if not
|
||||
if ! pgrep -xq "DEPNotify"; then
|
||||
startDEPNotify
|
||||
fi
|
||||
itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
|
||||
if [[ "$itemName" != "#" ]]; then
|
||||
depnotify_command "Status: $itemName installing…"
|
||||
else
|
||||
depnotify_command "Status: $item installing…"
|
||||
fi
|
||||
printlog "$item $itemName"
|
||||
cmdOutput="$( ${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true )"
|
||||
#cmdOutput="2022-05-19 13:20:45 : REQ : installomator : ################## End Installomator, exit code 0"
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
printlog "${item} succesfully installed."
|
||||
warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text "WARN" || true )"
|
||||
printlog "$warnOutput"
|
||||
else
|
||||
printlog "Error installing ${item}. Exit code ${exitStatus}"
|
||||
#printlog "$cmdOutput"
|
||||
errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
printlog "$errorOutput"
|
||||
((errorCount++))
|
||||
errorLabels="$errorLabels ${item}"
|
||||
fi
|
||||
((countLabels--))
|
||||
itemName=""
|
||||
done
|
||||
|
||||
# Mark: Finishing
|
||||
# Prevent re-run of script if conditionFile is set
|
||||
if [[ ! -z "$conditionFile" ]]; then
|
||||
printlog "Touching condition file so script will not run again"
|
||||
touch "$conditionFile" || true
|
||||
printlog "$(ls -al "$conditionFile" || true)"
|
||||
fi
|
||||
|
||||
# Show error to user if any
|
||||
printlog "Errors: $errorCount"
|
||||
if [[ $errorCount -ne 0 ]]; then
|
||||
errorMessage="${errorMessage} Total errors: $errorCount"
|
||||
message="$errorMessage"
|
||||
displayDialog &
|
||||
endMessage="$message"
|
||||
printlog "errorLabels: $errorLabels"
|
||||
fi
|
||||
|
||||
depnotify_command "Command: MainText: $endMessage"
|
||||
depnotify_command "Command: Quit: $endMessage"
|
||||
|
||||
sleep 1
|
||||
printlog "Remove $(rm -fv $DEPNOTIFY_LOG || true)"
|
||||
|
||||
printlog "Ending"
|
||||
caffexit $errorCount
|
||||
309
MDM/Installomator 1st Auto-install.sh
Executable file
309
MDM/Installomator 1st Auto-install.sh
Executable file
@@ -0,0 +1,309 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installomator 1st installation (auto installation at enrollment)
|
||||
instance="" # Name of used instance
|
||||
|
||||
LOGO="" # "appstore", "jamf", "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
items=(dialog dockutil microsoftautoupdate supportapp xink zohoworkdrivetruesync textmate applenyfonts applesfpro applesfmono applesfcompact 1password7 wwdc theunarchiver keka microsoftedge microsoftteams microsoftonedrive microsoftoffice365)
|
||||
# Remember: dialog dockutil
|
||||
|
||||
installomatorOptions="NOTIFY=silent BLOCKING_PROCESS_ACTION=ignore INSTALL=force IGNORE_APP_STORE_APPS=yes LOGGING=REQ"
|
||||
|
||||
# Error message to user if any occur
|
||||
showError="1" # Show error message if 1 (0 if it should not be shown)
|
||||
errorMessage="A problem was encountered setting up this Mac. Please contact IT."
|
||||
|
||||
######################################################################
|
||||
# Installomator 1st
|
||||
#
|
||||
# Installation using Installomator
|
||||
# (use separate Progress 1st script to show progress)
|
||||
# No customization below…
|
||||
######################################################################
|
||||
# This script can be used to install software using Installomator.
|
||||
# Script will display a dialog if any errors happens.
|
||||
# User is not notified about installations.
|
||||
######################################################################
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
#
|
||||
# This script made by Søren Theilgaard
|
||||
# https://github.com/Theile
|
||||
# Twitter and MacAdmins Slack: @theilgaard
|
||||
#
|
||||
# Some functions and code from Installomator:
|
||||
# https://github.com/Installomator/Installomator
|
||||
#
|
||||
######################################################################
|
||||
scriptVersion="9.6"
|
||||
# v. 9.6 : 2022-11-15 : GitHub API call is first, only try alternative if that fails.
|
||||
# v. 9.5 : 2022-09-21 : change of GitHub download
|
||||
# v. 9.4 : 2022-09-14 : Making error message optional. downloadURL can fall back on GitHub API.
|
||||
# v. 9.3 : 2022-08-29 : installomatorOptions in quotes and ignore blocking processes. Improved installation with looping if it fails, so it can try again. Improved GitHub handling. ws1 support.
|
||||
# v. 9.2.2 : 2022-06-17 : installomatorOptions introduced. Check 1.1.1.1 for internet connection.
|
||||
# v. 9.2.1 : 2022-05-30 : Some changes to logging
|
||||
# v. 9.2 : 2022-05-19 : Built in installer for Installomator, and display dialog if error happens. Now universal script for all supported MDMs based on LOGO variable.
|
||||
######################################################################
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# Check before running
|
||||
case $LOGO in
|
||||
addigy|microsoft)
|
||||
conditionFile="/var/db/.Installomator1stDone"
|
||||
# Addigy and Microsoft Endpoint Manager (Intune) need a check for a touched file
|
||||
if [ -e "$conditionFile" ]; then
|
||||
echo "$LOGO setup detected"
|
||||
echo "$conditionFile exists, so we exit."
|
||||
exit 0
|
||||
else
|
||||
echo "$conditionFile not found, so we continue…"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Mark: Constants, logging and caffeinate
|
||||
log_message="$instance: Installomator 1st, v$scriptVersion"
|
||||
label="1st-v$scriptVersion"
|
||||
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
printlog(){
|
||||
timestamp=$(date +%F\ %T)
|
||||
if [[ "$(whoami)" == "root" ]]; then
|
||||
echo "$timestamp :: $label : $1" | tee -a $log_location
|
||||
else
|
||||
echo "$timestamp :: $label : $1"
|
||||
fi
|
||||
}
|
||||
printlog "[LOG-BEGIN] ${log_message}"
|
||||
|
||||
# Internet check
|
||||
if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
|
||||
printlog "ERROR. No internet connection, we cannot continue."
|
||||
caffexit 90
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid" || true
|
||||
pkill caffeinate || true
|
||||
printlog "[LOG-END] Status $1"
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Counters
|
||||
errorCount=0
|
||||
countLabels=${#items[@]}
|
||||
printlog "Total installations: $countLabels"
|
||||
|
||||
# Using LOGO variable to specify MDM and shown logo
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
printlog "LOGO: $LOGO – LOGO_PATH: $LOGO_PATH"
|
||||
|
||||
# Mark: Functions
|
||||
# Notify the user using AppleScript
|
||||
function displayDialog(){
|
||||
currentUser="$(stat -f "%Su" /dev/console)"
|
||||
currentUserID=$(id -u "$currentUser")
|
||||
if [[ "$currentUser" != "" ]]; then
|
||||
launchctl asuser $currentUserID sudo -u $currentUser osascript -e "button returned of (display dialog \"$message\" buttons {\"OK\"} default button \"OK\" with icon POSIX file \"$LOGO_PATH\")" || true
|
||||
fi
|
||||
}
|
||||
|
||||
# Mark: Code
|
||||
name="Installomator"
|
||||
printlog "$name check for installation"
|
||||
# download URL, version and Expected Team ID
|
||||
# Method for GitHub pkg
|
||||
gitusername="Installomator"
|
||||
gitreponame="Installomator"
|
||||
#printlog "$gitusername $gitreponame"
|
||||
filetype="pkg"
|
||||
downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
|
||||
printlog "GitHub API failed, trying failover."
|
||||
#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
fi
|
||||
#printlog "$downloadURL"
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
|
||||
#printlog "$appNewVersion"
|
||||
expectedTeamID="JME5BW3F3R"
|
||||
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
currentInstalledVersion="$(${destFile} version 2>/dev/null || true)"
|
||||
printlog "${destFile} version: $currentInstalledVersion"
|
||||
if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
|
||||
printlog "$name not found or version not latest."
|
||||
printlog "${destFile}"
|
||||
printlog "Installing version ${appNewVersion} ..."
|
||||
# Create temporary working directory
|
||||
tmpDir="$(mktemp -d || true)"
|
||||
printlog "Created working directory '$tmpDir'"
|
||||
# Download the installer package
|
||||
printlog "Downloading $name package version $appNewVersion from: $downloadURL"
|
||||
installationCount=0
|
||||
exitCode=9
|
||||
while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
|
||||
curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
|
||||
curlDownloadStatus=$(echo $?)
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
printlog "error downloading $downloadURL, with status $curlDownloadStatus"
|
||||
printlog "${curlDownload}"
|
||||
exitCode=1
|
||||
else
|
||||
printlog "Download $name succes."
|
||||
# Verify the download
|
||||
teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
|
||||
printlog "Team ID for downloaded package: $teamID"
|
||||
# Install the package if Team ID validates
|
||||
if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
|
||||
printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
|
||||
pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
|
||||
pkgInstallStatus=$(echo $?)
|
||||
if [[ $pkgInstallStatus -ne 0 ]]; then
|
||||
printlog "ERROR. $name package installation failed."
|
||||
printlog "${pkgInstall}"
|
||||
exitCode=2
|
||||
else
|
||||
printlog "Installing $name package succes."
|
||||
exitCode=0
|
||||
fi
|
||||
else
|
||||
printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
|
||||
exitCode=3
|
||||
fi
|
||||
fi
|
||||
((installationCount++))
|
||||
printlog "$installationCount time(s), exitCode $exitCode"
|
||||
if [[ $installationCount -lt 3 ]]; then
|
||||
if [[ $exitCode -gt 0 ]]; then
|
||||
printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
|
||||
printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
|
||||
sleep 2
|
||||
fi
|
||||
else
|
||||
printlog "Download and install of $name succes."
|
||||
fi
|
||||
done
|
||||
# Remove the temporary working directory
|
||||
printlog "Deleting working directory '$tmpDir' and its contents."
|
||||
printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
|
||||
# Handle installation errors
|
||||
if [[ $exitCode != 0 ]]; then
|
||||
printlog "ERROR. Installation of $name failed. Aborting."
|
||||
caffexit $exitCode
|
||||
else
|
||||
printlog "$name version $appNewVersion installed!"
|
||||
fi
|
||||
else
|
||||
printlog "$name version $appNewVersion already found. Perfect!"
|
||||
fi
|
||||
|
||||
errorLabels=""
|
||||
((countLabels++))
|
||||
((countLabels--))
|
||||
printlog "$countLabels labels to install"
|
||||
|
||||
for item in "${items[@]}"; do
|
||||
printlog "$item"
|
||||
cmdOutput="$( ${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true )"
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
printlog "${item} succesfully installed."
|
||||
warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text "WARN" || true )"
|
||||
printlog "$warnOutput"
|
||||
else
|
||||
printlog "Error installing ${item}. Exit code ${exitStatus}"
|
||||
#printlog "$cmdOutput"
|
||||
errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
printlog "$errorOutput"
|
||||
((errorCount++))
|
||||
errorLabels="$errorLabels ${item}"
|
||||
fi
|
||||
((countLabels--))
|
||||
itemName=""
|
||||
done
|
||||
|
||||
# Mark: Finishing
|
||||
# Prevent re-run of script if conditionFile is set
|
||||
if [[ ! -z "$conditionFile" ]]; then
|
||||
printlog "Touching condition file so script will not run again"
|
||||
touch "$conditionFile" || true
|
||||
printlog "$(ls -al "$conditionFile" || true)"
|
||||
fi
|
||||
|
||||
# Show error to user if any
|
||||
printlog "Errors: $errorCount"
|
||||
if [[ $errorCount -ne 0 ]]; then
|
||||
printlog "ERROR: Display error dialog to user!"
|
||||
errorMessage="${errorMessage} Total errors: $errorCount"
|
||||
if [[ $showError -eq 1 ]]; then
|
||||
message="$errorMessage"
|
||||
displayDialog &
|
||||
fi
|
||||
printlog "errorLabels: $errorLabels"
|
||||
fi
|
||||
|
||||
printlog "Ending"
|
||||
caffexit $errorCount
|
||||
361
MDM/Installomator 1st SS DEPNotify.sh
Executable file
361
MDM/Installomator 1st SS DEPNotify.sh
Executable file
@@ -0,0 +1,361 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installomator 1st installation with DEPNotify window (for self Service deployment)
|
||||
instance="" # Name of used instance
|
||||
|
||||
LOGO="" # "appstore", "jamf", "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
items=(dialog dockutil microsoftautoupdate supportapp applenyfonts applesfpro applesfmono applesfcompact xink zohoworkdrivetruesync textmate 1password7 wwdc theunarchiver keka microsoftedge microsoftteams microsoftonedrive microsoftoffice365)
|
||||
# Remember: dialog dockutil
|
||||
|
||||
installomatorOptions="NOTIFY=all BLOCKING_PROCESS_ACTION=prompt_user"
|
||||
|
||||
# DEPNotify display settings, change as desired
|
||||
title="Installing Apps and other software"
|
||||
message="Please wait while we download and install the needed software."
|
||||
endMessage="Installation complete! Please reboot to activate FileVault."
|
||||
errorMessage="A problem was encountered setting up this Mac. Please contact IT."
|
||||
|
||||
######################################################################
|
||||
# Installomator 1st DEPNotify
|
||||
#
|
||||
# Installation using Installomator showing progress with DEPNotify
|
||||
# Great stand-alone solution if installs are only done using Installomator.
|
||||
# No customization below…
|
||||
######################################################################
|
||||
# This script can be used to install software using Installomator.
|
||||
# Script will start DEPNotify to display a progress bar.
|
||||
# Progress bar moves between installations
|
||||
######################################################################
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
#
|
||||
# This script made by Søren Theilgaard
|
||||
# https://github.com/Theile
|
||||
# Twitter and MacAdmins Slack: @theilgaard
|
||||
#
|
||||
# Some functions and code from Installomator:
|
||||
# https://github.com/Installomator/Installomator
|
||||
#
|
||||
######################################################################
|
||||
scriptVersion="9.6"
|
||||
# v. 9.6 : 2022-11-15 : GitHub API call is first, only try alternative if that fails.
|
||||
# v. 9.5 : 2022-09-21 : change of GitHub download
|
||||
# v. 9.4 : 2022-09-14 : downloadURL can fall back on GitHub API
|
||||
# v. 9.3 : 2022-08-29 : installomatorOptions in quotes and ignore blocking processes. Improved installation with looping if it fails, so it can try again. Improved GitHub handling. ws1 support.
|
||||
# v. 9.2.2 : 2022-06-17 : installomatorOptions introduced. Check 1.1.1.1 for internet connection.
|
||||
# v. 9.2.1 : 2022-05-30 : Some changes to logging
|
||||
# v. 9.2 : 2022-05-19 : Built in installer for Installlomator, and display dialog if error happens. Now universal script for all supported MDMs based on LOGO variable.
|
||||
# v. 9.1 : 2022-04-13 : Using INSTALL=force in Label only, so Microsoft labels will not start updating
|
||||
# v. 9.0.1 : 2022-02-21 : LOGO=addigy, few more "true" lines, and errorOutput on error
|
||||
# v. 9.0.0 : 2022-02-14 : Updated for Inst. 9.0, Logging improved with printlog
|
||||
######################################################################
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# Check before running
|
||||
case $LOGO in
|
||||
addigy|microsoft)
|
||||
conditionFile="/var/db/.Installomator1stDone"
|
||||
# Addigy and Microsoft Endpoint Manager (Intune) need a check for a touched file
|
||||
if [ -e "$conditionFile" ]; then
|
||||
echo "$LOGO setup detected"
|
||||
echo "$conditionFile exists, so we exit."
|
||||
exit 0
|
||||
else
|
||||
echo "$conditionFile not found, so we continue…"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Mark: Constants, logging and caffeinate
|
||||
log_message="$instance: Installomator 1st with DEPNotify, v$scriptVersion"
|
||||
label="1st-v$scriptVersion"
|
||||
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
printlog(){
|
||||
timestamp=$(date +%F\ %T)
|
||||
if [[ "$(whoami)" == "root" ]]; then
|
||||
echo "$timestamp :: $label : $1" | tee -a $log_location
|
||||
else
|
||||
echo "$timestamp :: $label : $1"
|
||||
fi
|
||||
}
|
||||
printlog "[LOG-BEGIN] ${log_message}"
|
||||
|
||||
# Internet check
|
||||
if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
|
||||
printlog "ERROR. No internet connection, we cannot continue."
|
||||
exit 90
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid" || true
|
||||
pkill caffeinate || true
|
||||
printlog "[LOG-END] Status $1"
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Command-file to DEPNotify
|
||||
DEPNOTIFY_LOG="/var/tmp/depnotify.log"
|
||||
|
||||
# Counters
|
||||
errorCount=0
|
||||
countLabels=${#items[@]}
|
||||
printlog "Total installations: $countLabels"
|
||||
|
||||
# Using LOGO variable to specify MDM and shown logo
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
printlog "LOGO: $LOGO - LOGO_PATH: $LOGO_PATH"
|
||||
|
||||
# Mark: Functions
|
||||
printlog "depnotify_command function"
|
||||
echo "" > $DEPNOTIFY_LOG || true
|
||||
function depnotify_command(){
|
||||
printlog "DEPNotify-command: $1"
|
||||
echo "$1" >> $DEPNOTIFY_LOG || true
|
||||
}
|
||||
|
||||
printlog "startDEPNotify function"
|
||||
function startDEPNotify() {
|
||||
currentUser="$(stat -f "%Su" /dev/console)"
|
||||
currentUserID=$(id -u "$currentUser")
|
||||
launchctl asuser $currentUserID open -a "/Applications/Utilities/DEPNotify.app/Contents/MacOS/DEPNotify" --args -path "$DEPNOTIFY_LOG" || true # --args -fullScreen
|
||||
sleep 5
|
||||
depnotify_command "Command: KillCommandFile:"
|
||||
depnotify_command "Command: MainTitle: $title"
|
||||
depnotify_command "Command: Image: $LOGO_PATH"
|
||||
depnotify_command "Command: MainText: $message"
|
||||
depnotify_command "Command: Determinate: $countLabels"
|
||||
}
|
||||
|
||||
# Notify the user using AppleScript
|
||||
printlog "displayDialog function"
|
||||
function displayDialog(){
|
||||
currentUser="$(stat -f "%Su" /dev/console)"
|
||||
currentUserID=$(id -u "$currentUser")
|
||||
if [[ "$currentUser" != "" ]]; then
|
||||
launchctl asuser $currentUserID sudo -u $currentUser osascript -e "button returned of (display dialog \"$message\" buttons {\"OK\"} default button \"OK\" with icon POSIX file \"$LOGO_PATH\")" || true
|
||||
fi
|
||||
}
|
||||
|
||||
# Mark: Code
|
||||
name="Installomator"
|
||||
printlog "$name check for installation"
|
||||
# download URL, version and Expected Team ID
|
||||
# Method for GitHub pkg
|
||||
gitusername="Installomator"
|
||||
gitreponame="Installomator"
|
||||
#printlog "$gitusername $gitreponame"
|
||||
filetype="pkg"
|
||||
downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
|
||||
printlog "GitHub API failed, trying failover."
|
||||
#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
fi
|
||||
#printlog "$downloadURL"
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
|
||||
#printlog "$appNewVersion"
|
||||
expectedTeamID="JME5BW3F3R"
|
||||
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
currentInstalledVersion="$(${destFile} version 2>/dev/null || true)"
|
||||
printlog "${destFile} version: $currentInstalledVersion"
|
||||
if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
|
||||
printlog "$name not found or version not latest."
|
||||
printlog "${destFile}"
|
||||
printlog "Installing version ${appNewVersion} ..."
|
||||
# Create temporary working directory
|
||||
tmpDir="$(mktemp -d || true)"
|
||||
printlog "Created working directory '$tmpDir'"
|
||||
# Download the installer package
|
||||
printlog "Downloading $name package version $appNewVersion from: $downloadURL"
|
||||
installationCount=0
|
||||
exitCode=9
|
||||
while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
|
||||
curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
|
||||
curlDownloadStatus=$(echo $?)
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
printlog "error downloading $downloadURL, with status $curlDownloadStatus"
|
||||
printlog "${curlDownload}"
|
||||
exitCode=1
|
||||
else
|
||||
printlog "Download $name succes."
|
||||
# Verify the download
|
||||
teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
|
||||
printlog "Team ID for downloaded package: $teamID"
|
||||
# Install the package if Team ID validates
|
||||
if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
|
||||
printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
|
||||
pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
|
||||
pkgInstallStatus=$(echo $?)
|
||||
if [[ $pkgInstallStatus -ne 0 ]]; then
|
||||
printlog "ERROR. $name package installation failed."
|
||||
printlog "${pkgInstall}"
|
||||
exitCode=2
|
||||
else
|
||||
printlog "Installing $name package succes."
|
||||
exitCode=0
|
||||
fi
|
||||
else
|
||||
printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
|
||||
exitCode=3
|
||||
fi
|
||||
fi
|
||||
((installationCount++))
|
||||
printlog "$installationCount time(s), exitCode $exitCode"
|
||||
if [[ $installationCount -lt 3 ]]; then
|
||||
if [[ $exitCode -gt 0 ]]; then
|
||||
printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
|
||||
printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
|
||||
sleep 2
|
||||
fi
|
||||
else
|
||||
printlog "Download and install of $name succes."
|
||||
fi
|
||||
done
|
||||
# Remove the temporary working directory
|
||||
printlog "Deleting working directory '$tmpDir' and its contents."
|
||||
printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
|
||||
# Handle installation errors
|
||||
if [[ $exitCode != 0 ]]; then
|
||||
printlog "ERROR. Installation of $name failed. Aborting."
|
||||
caffexit $exitCode
|
||||
else
|
||||
printlog "$name version $appNewVersion installed!"
|
||||
fi
|
||||
else
|
||||
printlog "$name version $appNewVersion already found. Perfect!"
|
||||
fi
|
||||
|
||||
# Installing DEPNotify
|
||||
cmdOutput="$( ${destFile} depnotify LOGO=$LOGO NOTIFY=silent BLOCKING_PROCESS_ACTION=ignore LOGGING=WARN || true )"
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
printlog "DEPNotify install result: $exitStatus"
|
||||
|
||||
itemName=""
|
||||
errorLabels=""
|
||||
((countLabels++))
|
||||
((countLabels--))
|
||||
printlog "$countLabels labels to install"
|
||||
|
||||
startDEPNotify
|
||||
|
||||
for item in "${items[@]}"; do
|
||||
# Check if DEPNotify is running and try open it if not
|
||||
if ! pgrep -xq "DEPNotify"; then
|
||||
startDEPNotify
|
||||
fi
|
||||
itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
|
||||
if [[ "$itemName" != "#" ]]; then
|
||||
depnotify_command "Status: $itemName installing…"
|
||||
else
|
||||
depnotify_command "Status: $item installing…"
|
||||
fi
|
||||
printlog "$item $itemName"
|
||||
cmdOutput="$( ${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true )"
|
||||
#cmdOutput="2022-05-19 13:20:45 : REQ : installomator : ################## End Installomator, exit code 0"
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
printlog "${item} succesfully installed."
|
||||
warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text "WARN" || true )"
|
||||
printlog "$warnOutput"
|
||||
else
|
||||
printlog "Error installing ${item}. Exit code ${exitStatus}"
|
||||
#printlog "$cmdOutput"
|
||||
errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
printlog "$errorOutput"
|
||||
((errorCount++))
|
||||
errorLabels="$errorLabels ${item}"
|
||||
fi
|
||||
((countLabels--))
|
||||
itemName=""
|
||||
done
|
||||
|
||||
# Mark: Finishing
|
||||
# Prevent re-run of script if conditionFile is set
|
||||
if [[ ! -z "$conditionFile" ]]; then
|
||||
printlog "Touching condition file so script will not run again"
|
||||
touch "$conditionFile" || true
|
||||
printlog "$(ls -al "$conditionFile" || true)"
|
||||
fi
|
||||
|
||||
# Show error to user if any
|
||||
printlog "Errors: $errorCount"
|
||||
if [[ $errorCount -ne 0 ]]; then
|
||||
errorMessage="${errorMessage} Total errors: $errorCount"
|
||||
message="$errorMessage"
|
||||
displayDialog &
|
||||
endMessage="$message"
|
||||
printlog "errorLabels: $errorLabels"
|
||||
fi
|
||||
|
||||
depnotify_command "Command: MainText: $endMessage"
|
||||
depnotify_command "Command: Quit: $endMessage"
|
||||
|
||||
sleep 1
|
||||
printlog "Remove $(rm -fv $DEPNOTIFY_LOG || true)"
|
||||
|
||||
printlog "Ending"
|
||||
caffexit $errorCount
|
||||
308
MDM/Installomator 1st SS.sh
Executable file
308
MDM/Installomator 1st SS.sh
Executable file
@@ -0,0 +1,308 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Installomator 1st installation (for Self Service deployment)
|
||||
instance="" # Name of used instance
|
||||
|
||||
LOGO="" # "appstore", "jamf", "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
items=(dialog dockutil microsoftautoupdate supportapp applenyfonts applesfpro applesfmono applesfcompact xink zohoworkdrivetruesync textmate 1password7 wwdc theunarchiver keka microsoftedge microsoftteams microsoftonedrive microsoftoffice365)
|
||||
# Remember: dialog dockutil
|
||||
|
||||
installomatorOptions="NOTIFY=all BLOCKING_PROCESS_ACTION=prompt_user"
|
||||
|
||||
# Error message to user if any occur
|
||||
showError="1" # Show error message if 1 (0 if it should not be shown)
|
||||
errorMessage="A problem was encountered setting up this Mac. Please contact IT."
|
||||
|
||||
######################################################################
|
||||
# Installomator 1st for Self Service
|
||||
#
|
||||
# Installation using Installomator
|
||||
# No customization below…
|
||||
######################################################################
|
||||
# This script can be used to install software using Installomator, where the user activate it in Self Service.
|
||||
# Script will display a dialog if any errors happens.
|
||||
# Progress is shown in notifications to the user
|
||||
######################################################################
|
||||
# Other installomatorOptions:
|
||||
# LOGGING=REQ
|
||||
# LOGGING=DEBUG
|
||||
# LOGGING=WARN
|
||||
# BLOCKING_PROCESS_ACTION=ignore
|
||||
# BLOCKING_PROCESS_ACTION=tell_user
|
||||
# BLOCKING_PROCESS_ACTION=tell_user_then_quit
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_loop
|
||||
# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
|
||||
# BLOCKING_PROCESS_ACTION=quit
|
||||
# BLOCKING_PROCESS_ACTION=kill
|
||||
# NOTIFY=all
|
||||
# NOTIFY=success
|
||||
# NOTIFY=silent
|
||||
# IGNORE_APP_STORE_APPS=yes
|
||||
# INSTALL=force
|
||||
######################################################################
|
||||
#
|
||||
# This script made by Søren Theilgaard
|
||||
# https://github.com/Theile
|
||||
# Twitter and MacAdmins Slack: @theilgaard
|
||||
#
|
||||
# Some functions and code from Installomator:
|
||||
# https://github.com/Installomator/Installomator
|
||||
#
|
||||
######################################################################
|
||||
scriptVersion="9.6"
|
||||
# v. 9.6 : 2022-11-15 : GitHub API call is first, only try alternative if that fails.
|
||||
# v. 9.5 : 2022-09-21 : change of GitHub download
|
||||
# v. 9.4 : 2022-09-14 : Making error message optional. downloadURL can fall back on GitHub API.
|
||||
# v. 9.3 : 2022-08-29 : installomatorOptions in quotes and ignore blocking processes. Improved installation with looping if it fails, so it can try again. Improved GitHub handling. ws1 support.
|
||||
# v. 9.2.2 : 2022-06-17 : installomatorOptions introduced. Check 1.1.1.1 for internet connection.
|
||||
# v. 9.2.1 : 2022-05-30 : Some changes to logging
|
||||
# v. 9.2 : 2022-05-19 : Built in installer for Installomator, and display dialog if error happens. Now universal script for all supported MDMs based on LOGO variable.
|
||||
######################################################################
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# Check before running
|
||||
case $LOGO in
|
||||
addigy|microsoft)
|
||||
conditionFile="/var/db/.Installomator1stDone"
|
||||
# Addigy and Microsoft Endpoint Manager (Intune) need a check for a touched file
|
||||
if [ -e "$conditionFile" ]; then
|
||||
echo "$LOGO setup detected"
|
||||
echo "$conditionFile exists, so we exit."
|
||||
exit 0
|
||||
else
|
||||
echo "$conditionFile not found, so we continue…"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Mark: Constants, logging and caffeinate
|
||||
log_message="$instance: Installomator 1st, v$scriptVersion"
|
||||
label="1st-v$scriptVersion"
|
||||
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
printlog(){
|
||||
timestamp=$(date +%F\ %T)
|
||||
if [[ "$(whoami)" == "root" ]]; then
|
||||
echo "$timestamp :: $label : $1" | tee -a $log_location
|
||||
else
|
||||
echo "$timestamp :: $label : $1"
|
||||
fi
|
||||
}
|
||||
printlog "[LOG-BEGIN] ${log_message}"
|
||||
|
||||
# Internet check
|
||||
if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
|
||||
printlog "ERROR. No internet connection, we cannot continue."
|
||||
caffexit 90
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid" || true
|
||||
pkill caffeinate || true
|
||||
printlog "[LOG-END] Status $1"
|
||||
exit $1
|
||||
}
|
||||
|
||||
# Counters
|
||||
errorCount=0
|
||||
countLabels=${#items[@]}
|
||||
printlog "Total installations: $countLabels"
|
||||
|
||||
# Using LOGO variable to specify MDM and shown logo
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
printlog "LOGO: $LOGO – LOGO_PATH: $LOGO_PATH"
|
||||
|
||||
# Mark: Functions
|
||||
# Notify the user using AppleScript
|
||||
function displayDialog(){
|
||||
currentUser="$(stat -f "%Su" /dev/console)"
|
||||
currentUserID=$(id -u "$currentUser")
|
||||
if [[ "$currentUser" != "" ]]; then
|
||||
launchctl asuser $currentUserID sudo -u $currentUser osascript -e "button returned of (display dialog \"$message\" buttons {\"OK\"} default button \"OK\" with icon POSIX file \"$LOGO_PATH\")" || true
|
||||
fi
|
||||
}
|
||||
|
||||
# Mark: Code
|
||||
name="Installomator"
|
||||
printlog "$name check for installation"
|
||||
# download URL, version and Expected Team ID
|
||||
# Method for GitHub pkg
|
||||
gitusername="Installomator"
|
||||
gitreponame="Installomator"
|
||||
#printlog "$gitusername $gitreponame"
|
||||
filetype="pkg"
|
||||
downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
|
||||
printlog "GitHub API failed, trying failover."
|
||||
#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
fi
|
||||
#printlog "$downloadURL"
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
|
||||
#printlog "$appNewVersion"
|
||||
expectedTeamID="JME5BW3F3R"
|
||||
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
currentInstalledVersion="$(${destFile} version 2>/dev/null || true)"
|
||||
printlog "${destFile} version: $currentInstalledVersion"
|
||||
if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
|
||||
printlog "$name not found or version not latest."
|
||||
printlog "${destFile}"
|
||||
printlog "Installing version ${appNewVersion} ..."
|
||||
# Create temporary working directory
|
||||
tmpDir="$(mktemp -d || true)"
|
||||
printlog "Created working directory '$tmpDir'"
|
||||
# Download the installer package
|
||||
printlog "Downloading $name package version $appNewVersion from: $downloadURL"
|
||||
installationCount=0
|
||||
exitCode=9
|
||||
while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
|
||||
curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
|
||||
curlDownloadStatus=$(echo $?)
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
printlog "error downloading $downloadURL, with status $curlDownloadStatus"
|
||||
printlog "${curlDownload}"
|
||||
exitCode=1
|
||||
else
|
||||
printlog "Download $name succes."
|
||||
# Verify the download
|
||||
teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
|
||||
printlog "Team ID for downloaded package: $teamID"
|
||||
# Install the package if Team ID validates
|
||||
if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
|
||||
printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
|
||||
pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
|
||||
pkgInstallStatus=$(echo $?)
|
||||
if [[ $pkgInstallStatus -ne 0 ]]; then
|
||||
printlog "ERROR. $name package installation failed."
|
||||
printlog "${pkgInstall}"
|
||||
exitCode=2
|
||||
else
|
||||
printlog "Installing $name package succes."
|
||||
exitCode=0
|
||||
fi
|
||||
else
|
||||
printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
|
||||
exitCode=3
|
||||
fi
|
||||
fi
|
||||
((installationCount++))
|
||||
printlog "$installationCount time(s), exitCode $exitCode"
|
||||
if [[ $installationCount -lt 3 ]]; then
|
||||
if [[ $exitCode -gt 0 ]]; then
|
||||
printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
|
||||
printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
|
||||
sleep 2
|
||||
fi
|
||||
else
|
||||
printlog "Download and install of $name succes."
|
||||
fi
|
||||
done
|
||||
# Remove the temporary working directory
|
||||
printlog "Deleting working directory '$tmpDir' and its contents."
|
||||
printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
|
||||
# Handle installation errors
|
||||
if [[ $exitCode != 0 ]]; then
|
||||
printlog "ERROR. Installation of $name failed. Aborting."
|
||||
caffexit $exitCode
|
||||
else
|
||||
printlog "$name version $appNewVersion installed!"
|
||||
fi
|
||||
else
|
||||
printlog "$name version $appNewVersion already found. Perfect!"
|
||||
fi
|
||||
|
||||
errorLabels=""
|
||||
((countLabels++))
|
||||
((countLabels--))
|
||||
printlog "$countLabels labels to install"
|
||||
|
||||
for item in "${items[@]}"; do
|
||||
printlog "$item"
|
||||
cmdOutput="$( ${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true )"
|
||||
exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
|
||||
if [[ ${exitStatus} -eq 0 ]] ; then
|
||||
printlog "${item} succesfully installed."
|
||||
warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text "WARN" || true )"
|
||||
printlog "$warnOutput"
|
||||
else
|
||||
printlog "Error installing ${item}. Exit code ${exitStatus}"
|
||||
#printlog "$cmdOutput"
|
||||
errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
|
||||
printlog "$errorOutput"
|
||||
((errorCount++))
|
||||
errorLabels="$errorLabels ${item}"
|
||||
fi
|
||||
((countLabels--))
|
||||
itemName=""
|
||||
done
|
||||
|
||||
# Mark: Finishing
|
||||
# Prevent re-run of script if conditionFile is set
|
||||
if [[ ! -z "$conditionFile" ]]; then
|
||||
printlog "Touching condition file so script will not run again"
|
||||
touch "$conditionFile" || true
|
||||
printlog "$(ls -al "$conditionFile" || true)"
|
||||
fi
|
||||
|
||||
# Show error to user if any
|
||||
printlog "Errors: $errorCount"
|
||||
if [[ $errorCount -ne 0 ]]; then
|
||||
printlog "ERROR: Display error dialog to user!"
|
||||
errorMessage="${errorMessage} Total errors: $errorCount"
|
||||
if [[ $showError -eq 1 ]]; then
|
||||
message="$errorMessage"
|
||||
displayDialog &
|
||||
fi
|
||||
printlog "errorLabels: $errorLabels"
|
||||
fi
|
||||
|
||||
printlog "Ending"
|
||||
caffexit $errorCount
|
||||
13
MDM/Installomator 1st condition.sh
Normal file
13
MDM/Installomator 1st condition.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Mark: Addigy Condition on condition file
|
||||
# Install on success
|
||||
|
||||
conditionFile="/var/db/.Installomator1stDone"
|
||||
if [ -e "$conditionFile" ]; then
|
||||
echo "$conditionFile exists. Exiting."
|
||||
exit 1
|
||||
else
|
||||
echo "$conditionFile not found. Continue…"
|
||||
exit 0
|
||||
fi
|
||||
11
MDM/Installomator 1st prevention.sh
Normal file
11
MDM/Installomator 1st prevention.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
# PREVENT Installomator 1st Auto-install from running
|
||||
|
||||
# DESCRIPTION
|
||||
# Will create the file to prevent Installomator 1st Auto-install from running.
|
||||
# Only for MDM solutions (like Addigy and Microsoft) that have conditions for runnning scripts and do not offer an enrollment event for runnning the script.
|
||||
# By runninng this script, the file will be created on the client, that will prevent Installomator 1st Auto-install from runnning.
|
||||
# This is a great help for implementing Installomator 1st Auto-install in a running solution, where the command below have to be run on currently enrolled devices, and then Installomator 1st Auto-install can be assigned to all machines, and will run only on newly enrolled devices.
|
||||
|
||||
/usr/bin/touch "/var/db/.Installomator1stDone"
|
||||
160
MDM/Jamf/00_PrepareInstall_SwiftDialog.sh
Executable file
160
MDM/Jamf/00_PrepareInstall_SwiftDialog.sh
Executable file
@@ -0,0 +1,160 @@
|
||||
#!/bin/zsh
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# MARK: Arguments/Parameters
|
||||
|
||||
# Parameter 4: path to the swiftDialog command file
|
||||
dialog_command_file=${4:-"/var/tmp/dialog.log"}
|
||||
|
||||
# Parameter 5: message displayed over the progress bar
|
||||
message=${5:-"Self Service Progress"}
|
||||
|
||||
# Parameter 6: path or URL to an icon
|
||||
icon=${6:-"/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"}
|
||||
# see Dan Snelson's advice on how to get a URL to an icon in Self Service
|
||||
# https://rumble.com/v119x6y-harvesting-self-service-icons.html
|
||||
|
||||
# MARK: Constants
|
||||
|
||||
dialogApp="/Library/Application Support/Dialog/Dialog.app"
|
||||
|
||||
# MARK: Functions
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand="$1"
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> "$dialog_command_file"
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
|
||||
# MARK: sanity checks
|
||||
|
||||
# check minimal macOS requirement
|
||||
if [[ $(sw_vers -buildVersion ) < "20A" ]]; then
|
||||
echo "This script requires at least macOS 11 Big Sur."
|
||||
exit 98
|
||||
fi
|
||||
|
||||
# check we are running as root
|
||||
if [[ $DEBUG -eq 0 && $(id -u) -ne 0 ]]; then
|
||||
echo "This script should be run as root"
|
||||
exit 97
|
||||
fi
|
||||
|
||||
# swiftDialog installation
|
||||
name="Dialog"
|
||||
echo "$name check for installation"
|
||||
# download URL, version and Expected Team ID
|
||||
# Method for GitHub pkg w. app version check
|
||||
gitusername="bartreardon"
|
||||
gitreponame="swiftDialog"
|
||||
#echo "$gitusername $gitreponame"
|
||||
filetype="pkg"
|
||||
downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
|
||||
printlog "GitHub API failed, trying failover."
|
||||
#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
fi
|
||||
#echo "$downloadURL"
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
|
||||
#echo "$appNewVersion"
|
||||
expectedTeamID="PWA5E9TQ59"
|
||||
destFile="/Library/Application Support/Dialog/Dialog.app"
|
||||
versionKey="CFBundleShortVersionString" #CFBundleVersion
|
||||
|
||||
currentInstalledVersion="$(defaults read "${destFile}/Contents/Info.plist" $versionKey || true)"
|
||||
echo "${name} version: $currentInstalledVersion"
|
||||
if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
|
||||
echo "$name not found or version not latest."
|
||||
echo "${destFile}"
|
||||
echo "Installing version ${appNewVersion}…"
|
||||
# Create temporary working directory
|
||||
tmpDir="$(mktemp -d || true)"
|
||||
echo "Created working directory '$tmpDir'"
|
||||
# Download the installer package
|
||||
echo "Downloading $name package version $appNewVersion from: $downloadURL"
|
||||
installationCount=0
|
||||
exitCode=9
|
||||
while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
|
||||
curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
|
||||
curlDownloadStatus=$(echo $?)
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
echo "error downloading $downloadURL, with status $curlDownloadStatus"
|
||||
echo "${curlDownload}"
|
||||
exitCode=1
|
||||
else
|
||||
echo "Download $name succes."
|
||||
# Verify the download
|
||||
teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
|
||||
echo "Team ID for downloaded package: $teamID"
|
||||
# Install the package if Team ID validates
|
||||
if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
|
||||
echo "$name package verified. Installing package '$tmpDir/$name.pkg'."
|
||||
pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
|
||||
pkgInstallStatus=$(echo $?)
|
||||
if [[ $pkgInstallStatus -ne 0 ]]; then
|
||||
echo "ERROR. $name package installation failed."
|
||||
echo "${pkgInstall}"
|
||||
exitCode=2
|
||||
else
|
||||
echo "Installing $name package succes."
|
||||
exitCode=0
|
||||
fi
|
||||
else
|
||||
echo "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
|
||||
exitCode=3
|
||||
fi
|
||||
fi
|
||||
((installationCount++))
|
||||
echo "$installationCount time(s), exitCode $exitCode"
|
||||
if [[ $installationCount -lt 3 ]]; then
|
||||
if [[ $exitCode -gt 0 ]]; then
|
||||
echo "Sleep a bit before trying download and install again. $installationCount time(s)."
|
||||
echo "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
|
||||
sleep 2
|
||||
fi
|
||||
else
|
||||
echo "Download and install of $name succes."
|
||||
fi
|
||||
done
|
||||
# Remove the temporary working directory
|
||||
echo "Deleting working directory '$tmpDir' and its contents."
|
||||
echo "Remove $(rm -Rfv "${tmpDir}" || true)"
|
||||
# Handle installation errors
|
||||
if [[ $exitCode != 0 ]]; then
|
||||
echo "ERROR. Installation of $name failed. Aborting."
|
||||
caffexit $exitCode
|
||||
else
|
||||
echo "$name version $appNewVersion installed!"
|
||||
fi
|
||||
else
|
||||
echo "$name version $appNewVersion already found. Perfect!"
|
||||
fi
|
||||
|
||||
# check for Swift Dialog
|
||||
if [[ ! -d $dialogApp ]]; then
|
||||
echo "Cannot find dialog at $dialogApp"
|
||||
exit 95
|
||||
fi
|
||||
|
||||
|
||||
# MARK: Configure and display swiftDialog
|
||||
|
||||
# display first screen
|
||||
open -a "$dialogApp" --args \
|
||||
--title none \
|
||||
--icon "$icon" \
|
||||
--message "$message" \
|
||||
--mini \
|
||||
--progress 100 \
|
||||
--position bottomright \
|
||||
--movable \
|
||||
--commandfile "$dialog_command_file"
|
||||
|
||||
# give everything a moment to catch up
|
||||
sleep 0.1
|
||||
69
MDM/Jamf/00_Prepare_SwiftDialog.sh
Executable file
69
MDM/Jamf/00_Prepare_SwiftDialog.sh
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/bin/zsh
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# MARK: Arguments/Parameters
|
||||
|
||||
# Parameter 4: path to the swiftDialog command file
|
||||
dialog_command_file=${4:-"/var/tmp/dialog.log"}
|
||||
|
||||
# Parameter 5: message displayed over the progress bar
|
||||
message=${5:-"Self Service Progress"}
|
||||
|
||||
# Parameter 6: path or URL to an icon
|
||||
icon=${6:-"/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"}
|
||||
# see Dan Snelson's advice on how to get a URL to an icon in Self Service
|
||||
# https://rumble.com/v119x6y-harvesting-self-service-icons.html
|
||||
|
||||
# MARK: Constants
|
||||
|
||||
dialogApp="/Library/Application Support/Dialog/Dialog.app"
|
||||
|
||||
# MARK: Functions
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand="$1"
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> "$dialog_command_file"
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
|
||||
# MARK: sanity checks
|
||||
|
||||
# check minimal macOS requirement
|
||||
if [[ $(sw_vers -buildVersion ) < "20A" ]]; then
|
||||
echo "This script requires at least macOS 11 Big Sur."
|
||||
exit 98
|
||||
fi
|
||||
|
||||
# check we are running as root
|
||||
if [[ $DEBUG -eq 0 && $(id -u) -ne 0 ]]; then
|
||||
echo "This script should be run as root"
|
||||
exit 97
|
||||
fi
|
||||
|
||||
# check for Swift Dialog
|
||||
if [[ ! -d $dialogApp ]]; then
|
||||
echo "Cannot find dialog at $dialogApp"
|
||||
exit 95
|
||||
fi
|
||||
|
||||
|
||||
# MARK: Configure and display swiftDialog
|
||||
|
||||
# display first screen
|
||||
open -a "$dialogApp" --args \
|
||||
--title none \
|
||||
--icon "$icon" \
|
||||
--message "$message" \
|
||||
--mini \
|
||||
--progress 100 \
|
||||
--position bottomright \
|
||||
--movable \
|
||||
--commandfile "$dialog_command_file"
|
||||
|
||||
# give everything a moment to catch up
|
||||
sleep 0.1
|
||||
48
MDM/Jamf/ReadMe.md
Normal file
48
MDM/Jamf/ReadMe.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Display Installomator Progress with SwiftDialog in Jamf
|
||||
|
||||
Installomator 10 has functionality to communicate with [Bart Reardon's swiftDialog](https://github.com/bartreardon/swiftDialog). When you set the `DIALOG_CMD_FILE` variable Installomator will write progress for downloads and installation (with pkgs) to the command file which allows swiftDialog to display the progress.
|
||||
|
||||
However, you have to launch and setup swiftDialog to display a window with a progress bar before Installomator launches and also make sure swiftDialog quits after Installomator has run. This may seem complex at first but allows to configure swiftDialog just for your case without needing to modify the Installomator script.
|
||||
|
||||
Here are some example script that would run before and after Installomator to display a swiftDialog window and quit the process after. Since Jamf Pro executes scripts in alphanumerical order, the names are chosen accordingly, to ensure proper order.
|
||||
|
||||
## Setup in Jamf Pro
|
||||
|
||||
To show Installomator progress with swiftDialog from a Jamf Policy, you require three scripts:
|
||||
|
||||
- `00_Prepare_SwiftDialog.sh`: Configures and displays the swiftDialog window
|
||||
- `Installomator.sh`: (v10 or higher)
|
||||
- `zz_Quit_SwiftDialog.sh`: quits swiftDialog
|
||||
|
||||
Add these three scripts to your Jamf Pro and create a policy with these three scripts. The names are chosen that the script appear in the correct order. If you rename the scripts in Jamf Pro, this may disrupt the order and the workflow will not work anymore. The "Priority" of the scripts in the policy should all be the same value.
|
||||
|
||||
The different scripts require a set of parameters. We will use the `googlechromepkg` label as an example.
|
||||
|
||||
`00_Prepare_SwiftDialog.sh`
|
||||
|
||||
Parameter 4: `/var/tmp/dialog.log` (Path to the swiftDialog command file)
|
||||
|
||||
Parameter 5: `Installing Google Chrome...` (text shown in the swiftDialog window above the progress bar)
|
||||
|
||||
Parameter 6: Path to or URL for an icon in swiftDialog. This can be a path on the client or a URL. See Dan Snelson's advice on how to get icon URLs for Self Service icons: https://rumble.com/v119x6y-harvesting-self-service-icons.html
|
||||
|
||||
`Installomator.sh`
|
||||
|
||||
Parameter 4: `googlechromepkg` (the label to install)
|
||||
|
||||
Parameter 5: `DIALOG_CMD_FILE=/var/tmp/dialog.log` (the swiftDialog command file, this has to be the same value as parameter 4 in the previous script)
|
||||
|
||||
Parameter 6: `NOTIFY=silent` (disable Installomator notifications, optional)
|
||||
|
||||
You can add more configurations to the Installomator script when needed.
|
||||
|
||||
`zz_Quit_SwiftDialog`
|
||||
|
||||
Parameter 4: `/var/tmp/dialog.log` (the swiftDialog command file, this has to be the same value as parameter 4 in the first script)
|
||||
|
||||
Then setup the remainder of the Jamf Policy to your needs. This works best with Self Service policies.
|
||||
|
||||
When you run the policy, the first script will configure and display swiftDialog. Installomator.sh will download and install the app while writing the proper update commands to the file set in `DIALOG_CMD_FILE`. The final script will quit swiftDialog.
|
||||
|
||||

|
||||
|
||||
BIN
MDM/Jamf/SelfServiceProgress.png
Normal file
BIN
MDM/Jamf/SelfServiceProgress.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 576 KiB |
57
MDM/Jamf/zz_Quit_SwiftDialog.sh
Executable file
57
MDM/Jamf/zz_Quit_SwiftDialog.sh
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/bin/zsh
|
||||
|
||||
# MARK: Arguments/Parameters
|
||||
|
||||
# Parameter 4: path to the swiftDialog command file
|
||||
dialog_command_file=${4:-"/var/tmp/dialog.log"}
|
||||
|
||||
# MARK: Constants
|
||||
dialogApp="/Library/Application Support/Dialog/Dialog.app"
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand="$1"
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> "$dialog_command_file"
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
|
||||
# check minimal macOS requirement
|
||||
if [[ $(sw_vers -buildVersion ) < "20A" ]]; then
|
||||
echo "This script requires at least macOS 11 Big Sur."
|
||||
exit 98
|
||||
fi
|
||||
|
||||
# check we are running as root
|
||||
if [[ $DEBUG -eq 0 && $(id -u) -ne 0 ]]; then
|
||||
echo "This script should be run as root"
|
||||
exit 97
|
||||
fi
|
||||
|
||||
# check for Swift Dialog
|
||||
if [[ ! -d $dialogApp ]]; then
|
||||
echo "Cannot find dialog at $dialogApp"
|
||||
exit 95
|
||||
fi
|
||||
|
||||
|
||||
# close and quit dialog
|
||||
dialogUpdate "progress: complete"
|
||||
dialogUpdate "progresstext: Done"
|
||||
|
||||
# pause a moment
|
||||
sleep 0.5
|
||||
|
||||
dialogUpdate "quit:"
|
||||
|
||||
# let everything catch up
|
||||
sleep 0.5
|
||||
|
||||
# just to be safe
|
||||
killall "Dialog"
|
||||
|
||||
# the killall command above will return error when Dialog is already quit
|
||||
# but we don't want that to register as a failure in Jamf, so always exit 0
|
||||
exit 0
|
||||
13
MDM/Progress 1st swiftDialog condition.sh
Normal file
13
MDM/Progress 1st swiftDialog condition.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Mark: Addigy Condition on condition file
|
||||
# Install on success
|
||||
|
||||
conditionFile="/var/db/.Progress1stDone"
|
||||
if [ -e "$conditionFile" ]; then
|
||||
echo "$conditionFile exists. Exiting."
|
||||
exit 1
|
||||
else
|
||||
echo "$conditionFile not found. Continue…"
|
||||
exit 0
|
||||
fi
|
||||
11
MDM/Progress 1st swiftDialog prevention.sh
Normal file
11
MDM/Progress 1st swiftDialog prevention.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
# PREVENT Progress 1st swiftDialog from running
|
||||
|
||||
# DESCRIPTION
|
||||
# Will create the file to prevent Progress 1st swiftDialog from running.
|
||||
# Only for MDM solutions (like Addigy and Microsoft) that have conditions for runnning scripts and do not offer an enrollment event for runnning the script.
|
||||
# By runninng this script, the file will be created on the client, that will prevent Progress 1st swiftDialog from runnning.
|
||||
# This is a great help for implementing Progress 1st swiftDialog in a running solution, where the command below have to be run on currently enrolled devices, and then Progress 1st swiftDialog can be assigned to all machines, and will run only on newly enrolled devices.
|
||||
|
||||
/usr/bin/touch "/var/db/.Progress1stDone"
|
||||
399
MDM/Progress 1st swiftDialog.sh
Executable file
399
MDM/Progress 1st swiftDialog.sh
Executable file
@@ -0,0 +1,399 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Progress 1st with swiftDialog (auto installation at enrollment)
|
||||
instance="" # Name of used instance
|
||||
|
||||
LOGO="" # "appstore", "jamf", "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
|
||||
|
||||
apps=(
|
||||
"swiftDialog,/usr/local/bin/dialog"
|
||||
"dockutil,/usr/local/bin/dockutil"
|
||||
"desktoppr,/usr/local/bin/desktoppr"
|
||||
"SupportApp,/Applications/Support.app"
|
||||
"Xink,/Applications/Xink.app"
|
||||
"Apple NewYork Font,/Library/Fonts/NewYork.ttf"
|
||||
"Apple SF Pro Font,/Library/Fonts/SF-Pro.ttf"
|
||||
"Apple SF Mono Font,/Library/Fonts/SF-Mono-Bold.otf"
|
||||
"Apple SF Compact Font,/Library/Fonts/SF-Compact.ttf"
|
||||
"Zoho WorkDrive TrueSync,/Applications/Zoho WorkDrive TrueSync.app"
|
||||
"TextMate,/Applications/TextMate.app"
|
||||
"Sublime Text,/Applications/Sublime Text.app"
|
||||
"1Password,/Applications/1Password 7.app"
|
||||
"Mactracker,/Applications/Mactracker.app"
|
||||
"WWDC,/Applications/WWDC.app"
|
||||
"The Unarchiver,/Applications/The Unarchiver.app"
|
||||
"Keka,/Applications/Keka.app"
|
||||
"Brave,/Applications/Brave Browser.app"
|
||||
"Firefox,/Applications/Firefox.app"
|
||||
"Microsoft AutoUpdate,/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app"
|
||||
"Microsoft Edge,/Applications/Microsoft Edge.app"
|
||||
"Microsoft Teams,/Applications/Microsoft Teams.app"
|
||||
"Microsoft Excel,/Applications/Microsoft Excel.app"
|
||||
"Microsoft OneNote,/Applications/Microsoft OneNote.app"
|
||||
"Microsoft Outlook,/Applications/Microsoft Outlook.app"
|
||||
"Microsoft PowerPoint,/Applications/Microsoft PowerPoint.app"
|
||||
"Microsoft Word,/Applications/Microsoft Word.app"
|
||||
"Microsoft OneDrive,/Applications/OneDrive.app"
|
||||
)
|
||||
|
||||
# Dialog display settings, change as desired
|
||||
title="Installing Apps and other software"
|
||||
message="Please wait while we download and install the needed software."
|
||||
endMessage="Installation complete! Please reboot to activate FileVault."
|
||||
displayEndMessageDialog=1 # Should endMessage be shown as a dialog? (0|1)
|
||||
errorMessage="A problem was encountered setting up this Mac. Please contact IT."
|
||||
|
||||
######################################################################
|
||||
# Progress 1st Dialog
|
||||
#
|
||||
# Showing installation progress using swiftDialog
|
||||
# No customization below…
|
||||
######################################################################
|
||||
# Complete script meant for running via MDM on device enrollment. This will download
|
||||
# and install Dialog on the fly before opening Dialog.
|
||||
#
|
||||
# Log: /private/var/log/InstallationProgress.log
|
||||
# This file prevents script from running again on Addigy and Microsoft Endpoint (Intune):
|
||||
# "/var/db/.Progress1stDone"
|
||||
#
|
||||
# Display a Dialog with a list of applications and indicate when they’ve been installed
|
||||
# Useful when apps are deployed at random, perhaps without local logging.
|
||||
# Applies to Mosyle App Catalog installs, VPP app installs, Installomator installs etc.
|
||||
# The script watches the existence of files in the file system, so that is used to show progress.
|
||||
#
|
||||
# Requires Dialog v1.9.1 or later (will be installed) https://github.com/bartreardon/swiftDialog
|
||||
#
|
||||
######################################################################
|
||||
#
|
||||
# This script made by Søren Theilgaard
|
||||
# https://github.com/Theile
|
||||
# Twitter and MacAdmins Slack: @theilgaard
|
||||
#
|
||||
# Based on the work by Adam Codega:
|
||||
# https://github.com/acodega/dialog-scripts
|
||||
#
|
||||
# Some functions and code from Installomator:
|
||||
# https://github.com/Installomator/Installomator
|
||||
#
|
||||
######################################################################
|
||||
# List of apps/installs to process in “apps” array.
|
||||
# Provide the display name as you prefer and the path to the app/file. ex:
|
||||
# "Google Chrome,/Applications/Google Chrome.app"
|
||||
# A comma separates the display name from the path. Do not use commas in your display name text.
|
||||
#
|
||||
# Tip: Check for something like print drivers using the pkg receipt, like:
|
||||
# "Konica-Minolta drivers,/var/db/receipts/jp.konicaminolta.print.package.C759.plist"
|
||||
# Or fonts, like:
|
||||
# "Apple SF Pro Font,/Library/Fonts/SF-Pro.ttf"
|
||||
######################################################################
|
||||
scriptVersion="9.6"
|
||||
# v. 9.6 : 2022-11-15 : GitHub API call is first, only try alternative if that fails.
|
||||
# v. 9.5 : 2022-09-21 : change of GitHub download
|
||||
# v. 9.4 : 2022-09-14 : downloadURL can fall back on GitHub API
|
||||
# v. 9.3 : 2022-08-29 : Logging changed for current version. Improved installation with looping if it fails, so it can try again. Improved GitHub handling.
|
||||
# v. 9.2.2 : 2022-06-17 : Improved Dialog installation. Check 1.1.1.1 for internet connection.
|
||||
# v. 9.2 : 2022-05-19 : Not using GitHub api for download of Dialog, show a dialog when finished to make message more important. Now universal script for all supported MDMs based on LOGO variable.
|
||||
# v. 9.0 : 2022-05-16 : Based on acodega’s work, I have added progress bar, changed logging and use another log-location, a bit more error handling for Dialog download, added some "|| true"-endings to some lines to not make them fail in Addigy, and some more.
|
||||
######################################################################
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# Check before running
|
||||
case $LOGO in
|
||||
addigy|microsoft)
|
||||
conditionFile="/var/db/.Progress1stDone"
|
||||
# Addigy and Microsoft Endpoint Manager (Intune) need a check for a touched file
|
||||
if [ -e "$conditionFile" ]; then
|
||||
echo "$LOGO setup detected"
|
||||
echo "$conditionFile exists, so we exit."
|
||||
exit 0
|
||||
else
|
||||
echo "$conditionFile not found, so we continue…"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Mark: Constants and logging
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
log_message="$instance: Progress 1st with Dialog, v$scriptVersion"
|
||||
label="P1st-v$scriptVersion"
|
||||
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
function printlog(){
|
||||
timestamp=$(date +%F\ %T)
|
||||
if [[ "$(whoami)" == "root" ]]; then
|
||||
echo "$timestamp :: $label : $1" | tee -a $log_location
|
||||
else
|
||||
echo "$timestamp :: $label : $1"
|
||||
fi
|
||||
}
|
||||
printlog "[LOG-BEGIN] ${log_message}"
|
||||
|
||||
# Internet check
|
||||
if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
|
||||
printlog "ERROR. No internet connection, we cannot continue."
|
||||
exit 90
|
||||
fi
|
||||
|
||||
# Location of dialog and dialog command file
|
||||
dialogApp="/usr/local/bin/dialog"
|
||||
dialog_command_file="/var/tmp/dialog.log"
|
||||
counterFile="/var/tmp/Progress1st.plist"
|
||||
|
||||
# Counters
|
||||
progress_index=0
|
||||
step_progress=0
|
||||
defaults write $counterFile step -int 0
|
||||
progress_total=${#apps[@]}
|
||||
printlog "Total watched installations: $progress_total"
|
||||
|
||||
# Using LOGO variable to specify MDM and shown logo
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
ws1)
|
||||
# Workspace ONE (AirWatch)
|
||||
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO_PATH}" ]]; then
|
||||
printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
|
||||
if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
printlog "LOGO: $LOGO – LOGO_PATH: $LOGO_PATH"
|
||||
|
||||
# Mark: Functions
|
||||
# execute a dialog command
|
||||
echo "" > $dialog_command_file || true
|
||||
function dialog_command(){
|
||||
printlog "Dialog-command: $1"
|
||||
echo "$1" >> $dialog_command_file || true
|
||||
}
|
||||
|
||||
function appCheck(){
|
||||
dialog_command "listitem: $(echo "$app" | cut -d ',' -f1): wait"
|
||||
while [ ! -e "$(echo "$app" | cut -d ',' -f2)" ]; do
|
||||
sleep 2
|
||||
done
|
||||
dialog_command "progresstext: Install of “$(echo "$app" | cut -d ',' -f1)” complete"
|
||||
dialog_command "listitem: $(echo "$app" | cut -d ',' -f1): ✅"
|
||||
progress_index=$(defaults read $counterFile step)
|
||||
progress_index=$(( progress_index + 1 ))
|
||||
defaults write $counterFile step -int $progress_index
|
||||
dialog_command "progress: $progress_index"
|
||||
printlog "at item number $progress_index"
|
||||
}
|
||||
|
||||
# Notify the user using AppleScript
|
||||
function displayDialog(){
|
||||
if [[ "$currentUser" != "" ]]; then
|
||||
launchctl asuser $currentUserID sudo -u $currentUser osascript -e "button returned of (display dialog \"$message\" buttons {\"OK\"} default button \"OK\" with icon POSIX file \"$LOGO_PATH\")" || true
|
||||
fi
|
||||
}
|
||||
|
||||
# Mark: Code
|
||||
name="Dialog"
|
||||
printlog "$name check for installation"
|
||||
# download URL, version and Expected Team ID
|
||||
# Method for GitHub pkg w. app version check
|
||||
gitusername="bartreardon"
|
||||
gitreponame="swiftDialog"
|
||||
#printlog "$gitusername $gitreponame"
|
||||
filetype="pkg"
|
||||
downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
|
||||
printlog "GitHub API failed, trying failover."
|
||||
#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
fi
|
||||
#printlog "$downloadURL"
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
|
||||
#printlog "$appNewVersion"
|
||||
expectedTeamID="PWA5E9TQ59"
|
||||
destFile="/Library/Application Support/Dialog/Dialog.app"
|
||||
versionKey="CFBundleShortVersionString" #CFBundleVersion
|
||||
|
||||
currentInstalledVersion="$(defaults read "${destFile}/Contents/Info.plist" $versionKey || true)"
|
||||
printlog "${name} version: $currentInstalledVersion"
|
||||
destFile="/usr/local/bin/dialog"
|
||||
if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
|
||||
printlog "$name not found or version not latest."
|
||||
printlog "${destFile}"
|
||||
printlog "Installing version ${appNewVersion}…"
|
||||
# Create temporary working directory
|
||||
tmpDir="$(mktemp -d || true)"
|
||||
printlog "Created working directory '$tmpDir'"
|
||||
# Download the installer package
|
||||
printlog "Downloading $name package version $appNewVersion from: $downloadURL"
|
||||
installationCount=0
|
||||
exitCode=9
|
||||
while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
|
||||
curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
|
||||
curlDownloadStatus=$(echo $?)
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
printlog "error downloading $downloadURL, with status $curlDownloadStatus"
|
||||
printlog "${curlDownload}"
|
||||
exitCode=1
|
||||
else
|
||||
printlog "Download $name succes."
|
||||
# Verify the download
|
||||
teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
|
||||
printlog "Team ID for downloaded package: $teamID"
|
||||
# Install the package if Team ID validates
|
||||
if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
|
||||
printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
|
||||
pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
|
||||
pkgInstallStatus=$(echo $?)
|
||||
if [[ $pkgInstallStatus -ne 0 ]]; then
|
||||
printlog "ERROR. $name package installation failed."
|
||||
printlog "${pkgInstall}"
|
||||
exitCode=2
|
||||
else
|
||||
printlog "Installing $name package succes."
|
||||
exitCode=0
|
||||
fi
|
||||
else
|
||||
printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
|
||||
exitCode=3
|
||||
fi
|
||||
fi
|
||||
((installationCount++))
|
||||
printlog "$installationCount time(s), exitCode $exitCode"
|
||||
if [[ $installationCount -lt 3 ]]; then
|
||||
if [[ $exitCode -gt 0 ]]; then
|
||||
printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
|
||||
printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
|
||||
sleep 2
|
||||
fi
|
||||
else
|
||||
printlog "Download and install of $name succes."
|
||||
fi
|
||||
done
|
||||
# Remove the temporary working directory
|
||||
printlog "Deleting working directory '$tmpDir' and its contents."
|
||||
printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
|
||||
# Handle installation errors
|
||||
if [[ $exitCode != 0 ]]; then
|
||||
printlog "ERROR. Installation of $name failed. Aborting."
|
||||
caffexit $exitCode
|
||||
else
|
||||
printlog "$name version $appNewVersion installed!"
|
||||
fi
|
||||
else
|
||||
printlog "$name version $appNewVersion already found. Perfect!"
|
||||
fi
|
||||
|
||||
|
||||
while [ "$(pgrep -l "Setup Assistant")" != "" ]; do
|
||||
printlog "Setup Assistant Still Running. PID $setupAssistantProcess."
|
||||
sleep 1
|
||||
done
|
||||
printlog "Out of Setup Assistant."
|
||||
|
||||
while [ "$(pgrep -l "Finder")" = "" ]; do
|
||||
printlog "Finder process not found. Assuming device is at login screen. PID $finderProcess"
|
||||
sleep 1
|
||||
done
|
||||
printlog "Finder is running…"
|
||||
|
||||
currentUser=$(stat -f "%Su" /dev/console)
|
||||
currentUserID=$(id -u "$currentUser")
|
||||
printlog "Logged in user is $currentUser with ID $currentUserID"
|
||||
|
||||
# set icon based on whether computer is a desktop or laptop
|
||||
#hwType=$(system_profiler SPHardwareDataType | grep "Model Identifier" | grep "Book" || true)
|
||||
#if [ "$hwType" != "" ]; then
|
||||
# LOGO_PATH="SF=laptopcomputer.and.arrow.down,weight=thin,colour1=#51a3ef,colour2=#5154ef"
|
||||
#else
|
||||
# LOGO_PATH="SF=desktopcomputer.and.arrow.down,weight=thin,colour1=#51a3ef,colour2=#5154ef"
|
||||
#fi
|
||||
|
||||
dialogCMD="$dialogApp -p --title \"$title\" \
|
||||
--message \"$message\" \
|
||||
--icon \"$LOGO_PATH\" \
|
||||
--progress $progress_total \
|
||||
--button1text \"Please Wait\" \
|
||||
--button1disabled"
|
||||
|
||||
# create the list of apps
|
||||
listitems=""
|
||||
for app in "${apps[@]}"; do
|
||||
listitems="$listitems --listitem '$(echo "$app" | cut -d ',' -f1)'"
|
||||
done
|
||||
|
||||
# final command to execute
|
||||
dialogCMD="$dialogCMD $listitems"
|
||||
|
||||
printlog "$dialogCMD"
|
||||
|
||||
# Launch dialog and run it in the background sleep for a second to let thing initialise
|
||||
printlog "About to launch Dialog."
|
||||
eval "$dialogCMD" &
|
||||
sleep 2
|
||||
|
||||
(for app in "${apps[@]}"; do
|
||||
#step_progress=$(( 1 + progress_index ))
|
||||
#dialog_command "progress: $step_progress"
|
||||
sleep 0.5
|
||||
appCheck &
|
||||
done
|
||||
|
||||
wait)
|
||||
|
||||
# Mark: Finishing
|
||||
|
||||
# Prevent re-run of script if conditionFile is set
|
||||
if [[ ! -z "$conditionFile" ]]; then
|
||||
printlog "Touching condition file so script will not run again"
|
||||
touch "$conditionFile" || true
|
||||
printlog "$(ls -al "$conditionFile" || true)"
|
||||
fi
|
||||
|
||||
# all done. close off processing and enable the "Done" button
|
||||
printlog "Finalizing."
|
||||
dialog_command "progresstext: $endMessage"
|
||||
dialog_command "progress: complete"
|
||||
dialog_command "button1text: Done"
|
||||
dialog_command "button1: enable"
|
||||
|
||||
if [[ $displayEndMessageDialog -eq 1 ]]; then
|
||||
message="$endMessage"
|
||||
displayDialog &
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
printlog $(rm -fv $dialog_command_file || true)
|
||||
printlog $(rm -fv $counterFile || true)
|
||||
|
||||
printlog "Ending"
|
||||
83
MDM/README.md
Normal file
83
MDM/README.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Scripts for use with MDM
|
||||
|
||||
These example scripts are meant for use with MDM to run __Installomator__ and process installs. Examples are also included which use swiftDialog to provide user feedback and dockutil to add app icons to the dock.
|
||||
|
||||
There are basically two ways to use Installomator with MDM. The _“Jamf way”_ is where, through the MDM admin interface, your upload the Installomator script to a policy, and you provide additional parameters in the policy configuration like which app to install. The _“other way”_ to use Installomator is by having the MDM install Installomator locally on the computer, just once, and then on subsequent runs the MDM runs a script which calls Installomator and provides the parameters.
|
||||
|
||||
Examples of MDMs which use the “other way” are Mosyle Manager/Mosyle Business, Addigy, and Microsoft Endpoint Manager (Intune).
|
||||
|
||||
The scripts utilizing __swiftDialog__ require version 10 of __Installomator__. If Installomator version 9 is installed, it will set `NOTIFY=all` and use the traditional __Installomator__ notifications for showing progress, where as on version 10 it will be `NOTIFY=silent` as __swiftDialog__ is used instead.
|
||||
|
||||
## Abbreviations used in script names
|
||||
|
||||
- SS — Self Service — scripts designed for use through a Self Service catalog
|
||||
- VFA — valuesfromarguments — a custom label call to Installomator. When using an MDM and the "other way", you can use these scripts to provide the label variables to Installomator for custom labels.
|
||||
|
||||
## Condition scripts
|
||||
|
||||
Scripts with the `condition` suffix are for use with MDMs like Addigy, where a script is run to determine if the rest of the policy should run.
|
||||
|
||||
## Prevention scripts
|
||||
|
||||
The `Installomator 1st` and `Progress 1st` scripts are meant to run automatically upon device enrollment. They check for the existance of a file, `/var/db/.Installomator1stDone`, to determine whether the computer has already been deployed. You can run the prevention scripts on existing Macs to ensure the 1st scripts won't inadvertently run on them.
|
||||
|
||||
## "Jamf" folder
|
||||
|
||||
This folder has Jamf specific examples using __swiftDialog__ as part of the Installomator installation. Perfect for use with Jamf Self Service. Separate [ReadMe-file](Jamf/ReadMe.md) in this folder.
|
||||
|
||||
# Scripts to install prerequisites
|
||||
|
||||
Use these scripts to handle installing Installomator itself. Additionally, you may want to install swiftDialog manually instead of having Installomator install it.
|
||||
|
||||
- `install Installomator direct.sh` — can be run at enrollment and as maintenance at any time to install __Installomator__.
|
||||
|
||||
- `install swiftDialog direct.sh` — can be used at enrollment and as maintenance at any time to install __swiftDialog__.
|
||||
|
||||
Once Installomator has been installed, __dockutil__ can be installed by Installomator, using this script:
|
||||
|
||||
- `App-install/App service Auto-install.sh` — This script uses pre-installed installomator to install __dockutil__.
|
||||
|
||||
# Enrollment scripts
|
||||
|
||||
For enrollment purposes, some 1st-scripts has been created. One runs silently, another is using __DEPNotify__ to show progress and feedback:
|
||||
|
||||
- `Installomator 1st Auto-install DEPNotify.sh` — will install __DEPNotify__ first, start that up, and change progress on the installation bar at each installed label. Very good for Addigy an Microsoft.
|
||||
|
||||
- `Installomator 1st Auto-install.sh` — runnning silently installing Installomator labels in the given order. Can be used in combination with the Progress-script.
|
||||
|
||||
- `Progress 1st swiftDialog.sh` — It will install __swiftDialog__ and start that up with a list of software it will look for. It will look for an installed file/folder in the file system for each item. This is great if some apps are being installed outside of Installomator, like by Apple Apps & Books, and then this script can show when it has been installed.
|
||||
|
||||
There are also Self Service versions of the above.
|
||||
|
||||
## “App-install”-folder
|
||||
|
||||
- App browser-security Auto-install.sh
|
||||
- App browser-security SS.sh
|
||||
- App normal Auto-install.sh
|
||||
- App normal SS.sh
|
||||
- App service Auto-install.sh
|
||||
- App VFA.sh
|
||||
|
||||
Here you can use scripts for Self Service (SS) or for Auto-install. There will be a difference in how many notifications will be used and maybe handling of blocking processes.
|
||||
|
||||
`browser-security`: For an app like a web browser, you’ll want the install performed right away, so there isn’t a deferral option.
|
||||
`normal`: The user can defer/skip the update.
|
||||
`service`: These are apps where we don’t need to ask the user to allow the update. Menu bar apps and utilities would fall under this category.
|
||||
|
||||
## “App-install SS with swiftDialog and dockutil”-folder
|
||||
|
||||
- App browser-security SS.sh
|
||||
- App normal SS multi-app.sh
|
||||
- App normal SS.sh
|
||||
- App service SS.sh
|
||||
- App VFA SS github.sh
|
||||
- App VFA SS.sh
|
||||
|
||||
These scripts are similar to the App-install folder but also utilize __swiftDialog__ to show user feedback and installation status, and they also have an option to use __dockutil__ to add the installed software to the Dock.
|
||||
|
||||
# App-update
|
||||
|
||||
A common requested behavior is to only update an app if it is already installed. These script verifies if the app is already installed before runnning Installomator.
|
||||
|
||||
- App browser-security Auto-install.sh
|
||||
- App normal Auto-install.sh
|
||||
13
MDM/Remove Installomator.sh
Normal file
13
MDM/Remove Installomator.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/zsh
|
||||
|
||||
# how to remove Installomator.
|
||||
|
||||
# Mark: This fork
|
||||
pkgutil --forget "com.scriptingosx.Installomator"
|
||||
rm /usr/local/Installomator/Installomator.sh
|
||||
rmdir /usr/local/Installomator
|
||||
|
||||
# Mark: Theile fork
|
||||
pkgutil --forget "dk.theilgaard.pkg.Installomator"
|
||||
rm /usr/local/bin/Installomator.sh
|
||||
rm /usr/local/bin/InstallomatorLabels.sh
|
||||
17
MDM/install Installomator direct condition.sh
Executable file
17
MDM/install Installomator direct condition.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Mark: Addigy Condition
|
||||
# Install on success
|
||||
|
||||
gitusername="Installomator"
|
||||
gitreponame="Installomator"
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
|
||||
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
if [[ ! -e "${destFile}" || "$(${destFile} version)" != "$appNewVersion" ]]; then
|
||||
#echo "Let's install…"
|
||||
exit 0
|
||||
else
|
||||
#echo "No need!"
|
||||
exit 1
|
||||
fi
|
||||
150
MDM/install Installomator direct.sh
Executable file
150
MDM/install Installomator direct.sh
Executable file
@@ -0,0 +1,150 @@
|
||||
#!/bin/sh
|
||||
|
||||
######################################################################
|
||||
# Installation of Installomator
|
||||
#
|
||||
# No customization below…
|
||||
######################################################################
|
||||
# This script can be used to install Installomator directly from GitHub.
|
||||
######################################################################
|
||||
#
|
||||
# This script made by Søren Theilgaard
|
||||
# https://github.com/Theile
|
||||
# Twitter and MacAdmins Slack: @theilgaard
|
||||
#
|
||||
# Some functions and code from Installomator:
|
||||
# https://github.com/Installomator/Installomator
|
||||
#
|
||||
######################################################################
|
||||
scriptVersion="9.6"
|
||||
# v. 9.6 : 2022-11-15 : GitHub API call is first, only try alternative if that fails.
|
||||
# v. 9.5 : 2022-09-21 : change of GitHub download
|
||||
# v. 9.4 : 2022-09-14 : downloadURL can fall back on GitHub API
|
||||
# v. 9.3 : 2022-08-29 : Logging changed for current version. Improved installation with looping if it fails, so it can try again. Improved GitHub handling.
|
||||
# v. 9.2.2 : 2022-06-17 : Check 1.1.1.1 for internet connection.
|
||||
# v. 9.2 : 2022-05-19 : Built in installer for Installlomator. Universal script.
|
||||
######################################################################
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# Mark: Constants, logging and caffeinate
|
||||
log_message="Installomator install, v$scriptVersion"
|
||||
label="Inst-v$scriptVersion"
|
||||
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
printlog(){
|
||||
timestamp=$(date +%F\ %T)
|
||||
if [[ "$(whoami)" == "root" ]]; then
|
||||
echo "$timestamp :: $label : $1" | tee -a $log_location
|
||||
else
|
||||
echo "$timestamp :: $label : $1"
|
||||
fi
|
||||
}
|
||||
printlog "[LOG-BEGIN] ${log_message}"
|
||||
|
||||
# Internet check
|
||||
if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
|
||||
printlog "ERROR. No internet connection, we cannot continue."
|
||||
exit 90
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid" || true
|
||||
pkill caffeinate || true
|
||||
printlog "[LOG-END] Status $1"
|
||||
exit $1
|
||||
}
|
||||
|
||||
name="Installomator"
|
||||
printlog "$name check for installation"
|
||||
# download URL, version and Expected Team ID
|
||||
# Method for GitHub pkg with destFile
|
||||
gitusername="Installomator"
|
||||
gitreponame="Installomator"
|
||||
#printlog "$gitusername $gitreponame"
|
||||
filetype="pkg"
|
||||
downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
|
||||
printlog "GitHub API failed, trying failover."
|
||||
#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
fi
|
||||
#printlog "$downloadURL"
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
|
||||
#printlog "$appNewVersion"
|
||||
expectedTeamID="JME5BW3F3R"
|
||||
|
||||
destFile="/usr/local/Installomator/Installomator.sh"
|
||||
currentInstalledVersion="$(${destFile} version 2>/dev/null || true)"
|
||||
printlog "${destFile} version: $currentInstalledVersion"
|
||||
if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
|
||||
printlog "$name not found or version not latest."
|
||||
printlog "${destFile}"
|
||||
printlog "Installing version ${appNewVersion} ..."
|
||||
# Create temporary working directory
|
||||
tmpDir="$(mktemp -d || true)"
|
||||
printlog "Created working directory '$tmpDir'"
|
||||
# Download the installer package
|
||||
printlog "Downloading $name package version $appNewVersion from: $downloadURL"
|
||||
installationCount=0
|
||||
exitCode=9
|
||||
while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
|
||||
curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
|
||||
curlDownloadStatus=$(echo $?)
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
printlog "error downloading $downloadURL, with status $curlDownloadStatus"
|
||||
printlog "${curlDownload}"
|
||||
exitCode=1
|
||||
else
|
||||
printlog "Download $name succes."
|
||||
# Verify the download
|
||||
teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
|
||||
printlog "Team ID for downloaded package: $teamID"
|
||||
# Install the package if Team ID validates
|
||||
if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
|
||||
printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
|
||||
pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
|
||||
pkgInstallStatus=$(echo $?)
|
||||
if [[ $pkgInstallStatus -ne 0 ]]; then
|
||||
printlog "ERROR. $name package installation failed."
|
||||
printlog "${pkgInstall}"
|
||||
exitCode=2
|
||||
else
|
||||
printlog "Installing $name package succes."
|
||||
exitCode=0
|
||||
fi
|
||||
else
|
||||
printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
|
||||
exitCode=3
|
||||
fi
|
||||
fi
|
||||
((installationCount++))
|
||||
printlog "$installationCount time(s), exitCode $exitCode"
|
||||
if [[ $installationCount -lt 3 ]]; then
|
||||
if [[ $exitCode -gt 0 ]]; then
|
||||
printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
|
||||
printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
|
||||
sleep 2
|
||||
fi
|
||||
else
|
||||
printlog "Download and install of $name succes."
|
||||
fi
|
||||
done
|
||||
# Remove the temporary working directory
|
||||
printlog "Deleting working directory '$tmpDir' and its contents."
|
||||
printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
|
||||
# Handle installation errors
|
||||
if [[ $exitCode != 0 ]]; then
|
||||
printlog "ERROR. Installation of $name failed. Aborting."
|
||||
caffexit $exitCode
|
||||
else
|
||||
printlog "$name version $appNewVersion installed!"
|
||||
fi
|
||||
else
|
||||
printlog "$name version $appNewVersion already found. Perfect!"
|
||||
fi
|
||||
|
||||
caffexit 0
|
||||
20
MDM/install swiftDialog direct condition.sh
Executable file
20
MDM/install swiftDialog direct condition.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Mark: Addigy Condition
|
||||
# Install on success
|
||||
|
||||
gitusername="bartreardon"
|
||||
gitreponame="swiftDialog"
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
|
||||
|
||||
destFile="/Library/Application Support/Dialog/Dialog.app"
|
||||
versionKey="CFBundleShortVersionString" #CFBundleVersion
|
||||
|
||||
currentInstalledVersion="$(defaults read "${destFile}/Contents/Info.plist" $versionKey || true)"
|
||||
if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
|
||||
#echo "Let's install…"
|
||||
exit 0
|
||||
else
|
||||
#echo "No need!"
|
||||
exit 1
|
||||
fi
|
||||
152
MDM/install swiftDialog direct.sh
Executable file
152
MDM/install swiftDialog direct.sh
Executable file
@@ -0,0 +1,152 @@
|
||||
#!/bin/sh
|
||||
|
||||
######################################################################
|
||||
# Installation of swiftDialog
|
||||
#
|
||||
# No customization below…
|
||||
######################################################################
|
||||
# This script can be used to install swiftDialog directly from GitHub.
|
||||
######################################################################
|
||||
#
|
||||
# This script made by Søren Theilgaard
|
||||
# https://github.com/Theile
|
||||
# Twitter and MacAdmins Slack: @theilgaard
|
||||
#
|
||||
# Some functions and code from Installomator:
|
||||
# https://github.com/Installomator/Installomator
|
||||
#
|
||||
######################################################################
|
||||
scriptVersion="9.6"
|
||||
# v. 9.6 : 2022-11-15 : GitHub API call is first, only try alternative if that fails.
|
||||
# v. 9.5 : 2022-09-21 : change of GitHub download
|
||||
# v. 9.4 : 2022-09-14 : downloadURL can fall back on GitHub API.
|
||||
# v. 9.3 : 2022-08-29 : Logging changed for current version. Improved installation with looping if it fails, so it can try again. Improved GitHub handling.
|
||||
# v. 9.2.2 : 2022-06-17 : Check 1.1.1.1 for internet connection.
|
||||
# v. 9.2 : 2022-05-19 : Built in installer for Installlomator. Universal script.
|
||||
######################################################################
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# Mark: Constants, logging and caffeinate
|
||||
log_message="Dialog install, v$scriptVersion"
|
||||
label="Dialog-v$scriptVersion"
|
||||
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
printlog(){
|
||||
timestamp=$(date +%F\ %T)
|
||||
if [[ "$(whoami)" == "root" ]]; then
|
||||
echo "$timestamp :: $label : $1" | tee -a $log_location
|
||||
else
|
||||
echo "$timestamp :: $label : $1"
|
||||
fi
|
||||
}
|
||||
printlog "[LOG-BEGIN] ${log_message}"
|
||||
|
||||
# Internet check
|
||||
if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
|
||||
printlog "ERROR. No internet connection, we cannot continue."
|
||||
exit 90
|
||||
fi
|
||||
|
||||
# No sleeping
|
||||
/usr/bin/caffeinate -d -i -m -u &
|
||||
caffeinatepid=$!
|
||||
caffexit () {
|
||||
kill "$caffeinatepid" || true
|
||||
pkill caffeinate || true
|
||||
printlog "[LOG-END] Status $1"
|
||||
exit $1
|
||||
}
|
||||
|
||||
name="Dialog"
|
||||
printlog "$name check for installation"
|
||||
# download URL, version and Expected Team ID
|
||||
# Method for GitHub pkg w. app version check
|
||||
gitusername="bartreardon"
|
||||
gitreponame="swiftDialog"
|
||||
#printlog "$gitusername $gitreponame"
|
||||
filetype="pkg"
|
||||
downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
|
||||
printlog "GitHub API failed, trying failover."
|
||||
#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
|
||||
fi
|
||||
#printlog "$downloadURL"
|
||||
appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
|
||||
#printlog "$appNewVersion"
|
||||
expectedTeamID="PWA5E9TQ59"
|
||||
destFile="/Library/Application Support/Dialog/Dialog.app"
|
||||
versionKey="CFBundleShortVersionString" #CFBundleVersion
|
||||
|
||||
currentInstalledVersion="$(defaults read "${destFile}/Contents/Info.plist" $versionKey || true)"
|
||||
printlog "${name} version: $currentInstalledVersion"
|
||||
destFile="/usr/local/bin/dialog"
|
||||
if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
|
||||
printlog "$name not found or version not latest."
|
||||
printlog "${destFile}"
|
||||
printlog "Installing version ${appNewVersion}…"
|
||||
# Create temporary working directory
|
||||
tmpDir="$(mktemp -d || true)"
|
||||
printlog "Created working directory '$tmpDir'"
|
||||
# Download the installer package
|
||||
printlog "Downloading $name package version $appNewVersion from: $downloadURL"
|
||||
installationCount=0
|
||||
exitCode=9
|
||||
while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
|
||||
curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
|
||||
curlDownloadStatus=$(echo $?)
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
printlog "error downloading $downloadURL, with status $curlDownloadStatus"
|
||||
printlog "${curlDownload}"
|
||||
exitCode=1
|
||||
else
|
||||
printlog "Download $name succes."
|
||||
# Verify the download
|
||||
teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
|
||||
printlog "Team ID for downloaded package: $teamID"
|
||||
# Install the package if Team ID validates
|
||||
if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
|
||||
printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
|
||||
pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
|
||||
pkgInstallStatus=$(echo $?)
|
||||
if [[ $pkgInstallStatus -ne 0 ]]; then
|
||||
printlog "ERROR. $name package installation failed."
|
||||
printlog "${pkgInstall}"
|
||||
exitCode=2
|
||||
else
|
||||
printlog "Installing $name package succes."
|
||||
exitCode=0
|
||||
fi
|
||||
else
|
||||
printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
|
||||
exitCode=3
|
||||
fi
|
||||
fi
|
||||
((installationCount++))
|
||||
printlog "$installationCount time(s), exitCode $exitCode"
|
||||
if [[ $installationCount -lt 3 ]]; then
|
||||
if [[ $exitCode -gt 0 ]]; then
|
||||
printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
|
||||
printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
|
||||
sleep 2
|
||||
fi
|
||||
else
|
||||
printlog "Download and install of $name succes."
|
||||
fi
|
||||
done
|
||||
# Remove the temporary working directory
|
||||
printlog "Deleting working directory '$tmpDir' and its contents."
|
||||
printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
|
||||
# Handle installation errors
|
||||
if [[ $exitCode != 0 ]]; then
|
||||
printlog "ERROR. Installation of $name failed. Aborting."
|
||||
caffexit $exitCode
|
||||
else
|
||||
printlog "$name version $appNewVersion installed!"
|
||||
fi
|
||||
else
|
||||
printlog "$name version $appNewVersion already found. Perfect!"
|
||||
fi
|
||||
|
||||
caffexit 0
|
||||
151
MDM/swiftdialog_example.sh
Executable file
151
MDM/swiftdialog_example.sh
Executable file
@@ -0,0 +1,151 @@
|
||||
#!/bin/zsh
|
||||
|
||||
# runs through a list of Installomator items
|
||||
# and displays status using Swift Dialog
|
||||
#
|
||||
# dependencies:
|
||||
# - Swift Dialog: https://github.com/bartreardon/swiftDialog
|
||||
# - Installomator: https://github.com/Installomator/Installomator
|
||||
# this script will install both if they are not yet present
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# MARK: Variables
|
||||
|
||||
# set to 1 to not require root and not actually do any changes
|
||||
# set to 0 for production
|
||||
if [[ $1 == "NODEBUG" ]]; then
|
||||
DEBUG=0
|
||||
else
|
||||
DEBUG=1
|
||||
fi
|
||||
|
||||
# the label to install:
|
||||
label="googlechromepkg"
|
||||
|
||||
|
||||
# MARK: Constants
|
||||
|
||||
scriptDir=$(dirname ${0:A})
|
||||
repoDir=$(dirname $scriptDir)
|
||||
|
||||
# if [[ $DEBUG -eq 1 ]]; then
|
||||
installomator="$repoDir/utils/assemble.sh"
|
||||
# else
|
||||
# installomator="/usr/local/Installomator/Installomator.sh"
|
||||
# fi
|
||||
|
||||
dialog="/usr/local/bin/dialog"
|
||||
|
||||
if [[ DEBUG -eq 0 ]]; then
|
||||
dialog_command_file="/var/tmp/dialog.log"
|
||||
else
|
||||
dialog_command_file="$HOME/dialog.log"
|
||||
fi
|
||||
|
||||
|
||||
# MARK: Functions
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand=$1
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> $dialog_command_file
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
|
||||
progressUpdate() {
|
||||
# $1: progress text (optional)
|
||||
local text=$1
|
||||
itemCounter=$((itemCounter + 1))
|
||||
dialogUpdate "progress: $itemCounter"
|
||||
if [[ -n $text ]]; then
|
||||
dialogUpdate "progresstext: $text"
|
||||
fi
|
||||
}
|
||||
|
||||
startItem() {
|
||||
local description=$1
|
||||
|
||||
echo "Starting Item: $description"
|
||||
dialogUpdate "listitem: $description: wait"
|
||||
progressUpdate $description
|
||||
}
|
||||
|
||||
cleanupAndExit() {
|
||||
# kill caffeinate process
|
||||
if [[ -n $caffeinatePID ]]; then
|
||||
echo "killing caffeinate..."
|
||||
kill $caffeinatePID
|
||||
fi
|
||||
|
||||
# clean up tmp dir
|
||||
if [[ -n $tmpDir && -d $tmpDir ]]; then
|
||||
echo "removing tmpDir $tmpDir"
|
||||
rm -rf $tmpDir
|
||||
fi
|
||||
}
|
||||
|
||||
# MARK: sanity checks
|
||||
|
||||
# check minimal macOS requirement
|
||||
if [[ $(sw_vers -buildVersion ) < "20" ]]; then
|
||||
echo "This script requires at least macOS 11 Big Sur."
|
||||
exit 98
|
||||
fi
|
||||
|
||||
# check we are running as root
|
||||
if [[ $DEBUG -eq 0 && $(id -u) -ne 0 ]]; then
|
||||
echo "This script should be run as root"
|
||||
exit 97
|
||||
fi
|
||||
|
||||
# check for installomator
|
||||
if [[ ! -x $installomator ]]; then
|
||||
echo "Cannot find Installomator at $installomator"
|
||||
exit 96
|
||||
fi
|
||||
|
||||
# check for Swift Dialog
|
||||
if [[ ! -x $dialog ]]; then
|
||||
echo "Cannot find dialog at $dialog"
|
||||
exit 95
|
||||
fi
|
||||
|
||||
|
||||
# MARK: Setup
|
||||
|
||||
# No sleeping
|
||||
caffeinate -dimsu & caffeinatePID=$!
|
||||
|
||||
# trap exit for cleanup
|
||||
trap cleanupAndExit EXIT
|
||||
|
||||
# display first screen
|
||||
$dialog --title "Installing $label" \
|
||||
--message "" \
|
||||
--hideicon \
|
||||
--mini \
|
||||
--progress 100 \
|
||||
--position bottomright \
|
||||
--ontop \
|
||||
--movable \
|
||||
--commandfile $dialog_command_file & dialogPID=$!
|
||||
|
||||
sleep 0.1
|
||||
|
||||
$installomator $label \
|
||||
DIALOG_CMD_FILE="$dialog_command_file" \
|
||||
DEBUG=$DEBUG
|
||||
|
||||
# clean up UI
|
||||
|
||||
dialogUpdate "progress: complete"
|
||||
dialogUpdate "progresstext: Done"
|
||||
|
||||
sleep 0.5
|
||||
|
||||
dialogUpdate "quit:"
|
||||
|
||||
185
MDM/swiftdialog_list.sh
Executable file
185
MDM/swiftdialog_list.sh
Executable file
@@ -0,0 +1,185 @@
|
||||
#!/bin/zsh
|
||||
|
||||
# runs through a list of Installomator items
|
||||
# and displays status using Swift Dialog
|
||||
#
|
||||
# dependencies:
|
||||
# - Swift Dialog: https://github.com/bartreardon/swiftDialog
|
||||
# - Installomator: https://github.com/Installomator/Installomator
|
||||
# this script will install both if they are not yet present
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# MARK: Variables
|
||||
|
||||
# set to 1 to not require root and not actually do any changes
|
||||
# set to 0 for production
|
||||
if [[ $1 == "NODEBUG" ]]; then
|
||||
DEBUG=0
|
||||
else
|
||||
DEBUG=1
|
||||
fi
|
||||
|
||||
# list of Installomator labels
|
||||
|
||||
items=(
|
||||
"firefoxpkg|Firefox"
|
||||
"error|Expected Error"
|
||||
"googlechromepkg|Google Chrome"
|
||||
)
|
||||
|
||||
# MARK: Constants
|
||||
|
||||
scriptDir=$(dirname ${0:A})
|
||||
repoDir=$(dirname $scriptDir)
|
||||
|
||||
# if [[ $DEBUG -eq 1 ]]; then
|
||||
installomator="$repoDir/utils/assemble.sh"
|
||||
# else
|
||||
# installomator="/usr/local/Installomator/Installomator.sh"
|
||||
# fi
|
||||
|
||||
dialog="/usr/local/bin/dialog"
|
||||
|
||||
if [[ DEBUG -eq 0 ]]; then
|
||||
dialog_command_file="/var/tmp/dialog.log"
|
||||
else
|
||||
dialog_command_file="$HOME/dialog.log"
|
||||
fi
|
||||
|
||||
|
||||
# MARK: Functions
|
||||
|
||||
dialogUpdate() {
|
||||
# $1: dialog command
|
||||
local dcommand=$1
|
||||
|
||||
if [[ -n $dialog_command_file ]]; then
|
||||
echo "$dcommand" >> $dialog_command_file
|
||||
echo "Dialog: $dcommand"
|
||||
fi
|
||||
}
|
||||
|
||||
progressUpdate() {
|
||||
# $1: progress text (optional)
|
||||
local text=$1
|
||||
itemCounter=$((itemCounter + 1))
|
||||
dialogUpdate "progress: $itemCounter"
|
||||
if [[ -n $text ]]; then
|
||||
dialogUpdate "progresstext: $text"
|
||||
fi
|
||||
}
|
||||
|
||||
startItem() {
|
||||
local description=$1
|
||||
|
||||
echo "Starting Item: $description"
|
||||
dialogUpdate "listitem: $description: wait"
|
||||
progressUpdate $description
|
||||
}
|
||||
|
||||
installomator() {
|
||||
# $1: label
|
||||
# $2: description
|
||||
local label=$1
|
||||
local description=$2
|
||||
|
||||
$installomator $label \
|
||||
DIALOG_CMD_FILE=${(q)dialog_command_file} \
|
||||
DIALOG_LIST_ITEM_NAME=${(q)description} \
|
||||
DEBUG=$DEBUG \
|
||||
LOGGING=DEBUG
|
||||
}
|
||||
|
||||
cleanupAndExit() {
|
||||
# kill caffeinate process
|
||||
if [[ -n $caffeinatePID ]]; then
|
||||
echo "killing caffeinate..."
|
||||
kill $caffeinatePID
|
||||
fi
|
||||
|
||||
# clean up tmp dir
|
||||
if [[ -n $tmpDir && -d $tmpDir ]]; then
|
||||
echo "removing tmpDir $tmpDir"
|
||||
rm -rf $tmpDir
|
||||
fi
|
||||
}
|
||||
|
||||
# MARK: sanity checks
|
||||
|
||||
# check minimal macOS requirement
|
||||
if [[ $(sw_vers -buildVersion ) < "20" ]]; then
|
||||
echo "This script requires at least macOS 11 Big Sur."
|
||||
exit 98
|
||||
fi
|
||||
|
||||
# check we are running as root
|
||||
if [[ $DEBUG -eq 0 && $(id -u) -ne 0 ]]; then
|
||||
echo "This script should be run as root"
|
||||
exit 97
|
||||
fi
|
||||
|
||||
# check for installomator
|
||||
if [[ ! -x $installomator ]]; then
|
||||
echo "Cannot find Installomator at $installomator"
|
||||
exit 96
|
||||
fi
|
||||
|
||||
# check for Swift Dialog
|
||||
if [[ ! -x $dialog ]]; then
|
||||
echo "Cannot find dialog at $dialog"
|
||||
exit 95
|
||||
fi
|
||||
|
||||
|
||||
# MARK: Setup
|
||||
|
||||
# No sleeping
|
||||
caffeinate -dimsu & caffeinatePID=$!
|
||||
|
||||
# trap exit for cleanup
|
||||
trap cleanupAndExit EXIT
|
||||
|
||||
# setup first list
|
||||
itemCount=$((${#items} + 1))
|
||||
|
||||
listitems=( )
|
||||
|
||||
for item in $items; do
|
||||
label=$(cut -d '|' -f 1 <<< $item)
|
||||
description=$(cut -d '|' -f 2 <<< $item)
|
||||
listitems+=( "--listitem" ${description} )
|
||||
done
|
||||
|
||||
# display first screen
|
||||
$dialog --title "More Software" \
|
||||
--icon "SF=gear" \
|
||||
--message "We are downloading and installing some extra Apps..." \
|
||||
--progress $itemCount \
|
||||
"${listitems[@]}" \
|
||||
--button1disabled \
|
||||
--big \
|
||||
--ontop \
|
||||
--liststyle compact \
|
||||
--width 700 \
|
||||
--commandfile $dialog_command_file & dialogPID=$!
|
||||
sleep 0.1
|
||||
|
||||
itemCounter=0
|
||||
|
||||
for item in $items; do
|
||||
label=$(cut -d '|' -f 1 <<< $item)
|
||||
description=$(cut -d '|' -f 2 <<< $item)
|
||||
|
||||
startItem $description
|
||||
installomator $label $description
|
||||
done
|
||||
|
||||
# clean up UI
|
||||
|
||||
dialogUpdate "progress: complete"
|
||||
dialogUpdate "progresstext: Finished"
|
||||
|
||||
dialogUpdate "button1: enable"
|
||||
dialogUpdate "button1text: Done"
|
||||
|
||||
313
README.md
313
README.md
@@ -1,35 +1,80 @@
|
||||
# Note: The main repo is a beta version
|
||||
|
||||
Please locate “Releases” on the right, and download the latest 9.2 release (either pkg or zip) for a supported release.
|
||||
|
||||
# Installomator
|
||||
|
||||
_The one installer script to rule them all._
|
||||
|
||||
   
|
||||
   
|
||||
|
||||
This script is in the "we find it useful, it is working for us" stage.
|
||||
This script is in the “we find it useful, it is working for us” stage.
|
||||
|
||||
Your production and deployment environment will be different, please test thoroughly before rolling it out to your production.
|
||||
|
||||
I have put a lot of work into making it stable and safe, but I cannot - of course - make _any_ promises that it won't break in some not yet encountered edge case.
|
||||
We have put a lot of work into making it stable and safe, but we cannot - of course - make _any_ promises that it won't break in some not yet encountered edge case.
|
||||
|
||||
## Authors
|
||||
|
||||
Intallomator was originally inspired by the download scripts from William Smith and Sander Schram, and created by:
|
||||
- [Armin Briegel - @scriptingosx](https://github.com/scriptingosx)
|
||||
|
||||
Later on a few more members came on the project:
|
||||
- Isaac Ordonez - @issacatmann
|
||||
- [Søren Theilgaard - @Theile](https://github.com/Theile)
|
||||
- [Adam Codega - @acodega](https://github.com/acodega)
|
||||
|
||||
And with numerous contributions from many others.
|
||||
|
||||
## Support and Contributing
|
||||
|
||||
__Please note, that if you are contributing to this project with new labels or other suggestions in PRs, please put your changes in the files below `fragments`-folder. DO NOT edit the full `Installomator.sh` script. The full script is now a build of the fragments, and will be overwritten. See the [README.md](utils/README.md) file in the `utils` directory for detailed instructions.__
|
||||
|
||||
Discussion, support and advice around Installomator happens in the `#installomator` channel in the [MacAdmins.org Slack](https://macadmins.org). Go there for support questions.
|
||||
|
||||
Do not create an issue just when you have a questions, but do file an issue or pull request (PR) for bugs or wrong behavior. When in doubt, ask in the above Slack channel.
|
||||
|
||||
Please see [CONTRIBUTING.md](https://github.com/Installomator/Installomator/blob/dev/CONTRIBUTING.md) for how to contribute.
|
||||
|
||||
## More reading
|
||||
|
||||
Our wiki:
|
||||
|
||||
- [Wiki](https://github.com/Installomator/Installomator/wiki)
|
||||
|
||||
There are a few interesting post on Installomator on Armin’s weblog:
|
||||
|
||||
- [Introducing Installomator](https://scriptingosx.com/2020/05/introducing-installomator/)
|
||||
- [Using Installomator with Jamf Pro](https://scriptingosx.com/2020/06/using-installomator-with-jamf-pro/) by Mischa van der Bent
|
||||
|
||||
## Background
|
||||
|
||||
As a system engineer at [an Apple Authorized Enterprise Reseller](https://prowarehouse.nl), we manage a lot of Jamf instances.
|
||||
In the world of managing Apple Macs, organizations can have two different approaches to the management. Either the IT department will tightly manage and verify each piece of software, or they will just want the latest software to be deployed as fast as possible.
|
||||
|
||||
Some of these instances are tightly managed, i.e. the versions of the operating system and third party software are controlled and updates will only be pushed with the management system when the administration and security team went through an approval process and then the update is automated. This is an important and valid workflow and the right fit for many deployments.
|
||||
OK, maybe some software should be tightly managed and others not, but you get the point.
|
||||
|
||||
### Tightly managed
|
||||
|
||||
If your solution needs to be tightly managed, i.e. the versions of the operating system and third party software are controlled and updates will only be pushed with the management system when the administration and security team went through an approval process and then the update is automated. This is an important and valid workflow and the right fit for many deployments.
|
||||
|
||||
Installomator was _not_ written for these kinds of deployment.
|
||||
|
||||
If you are running this kind of deployment, you want to use [AutoPkg](https://github.com/autopkg/autopkg) and you can stop reading here.
|
||||
|
||||
There are other kinds of deployments, though. In these deployments the management system is merely used to "get the user ready" as quickly as possible when they set up a new machine, and to offer software from a self service portal. In these deployments, system and software installations are 'latest version available' and updates are user driven (though we do want to nag them).
|
||||
### Latest version always
|
||||
|
||||
These deployments are
|
||||
There are other kinds of deployments, though. In these deployments the management system is merely used to “get the user ready” as quickly as possible when they set up a new machine, and to offer software from a self service portal. In these deployments, system and software installations are ‘latest version available’ and updates are user driven (though we do want to nag them and push them).
|
||||
|
||||
Installomator can help with this.
|
||||
|
||||
These deployments can be
|
||||
|
||||
- user driven
|
||||
- low control
|
||||
- minimal maintenance effort
|
||||
- latest version is best
|
||||
|
||||
These are mostly 'user controlled' Macs and we (the admins) just want to assist the user in doing the right thing. And the right thing is (often) to install the latest versions and updates when they are available.
|
||||
These can be 'user controlled' Macs and we (the admins) just want to assist the user in doing the right thing. And the right thing is (often) to install the latest versions and updates when they are available.
|
||||
|
||||
The Mac App Store and software pushed through the Mac App Store follow this approach. When you manage and deploy software through the App Store — whether it is on iOS or macOS — neither the MacAdmin nor the user get a choice of the application version. They will get the latest version.
|
||||
|
||||
@@ -46,16 +91,25 @@ Some of these disadvantages can be seen as advantages in different setups. When
|
||||
|
||||
Because this is an attractive solution for _certain kinds_ of deployment, there are already many scripts out there that will download and install the latest version of a given software. And we have built and used quite a few in-house, as well. Most importantly, [William Smith has this script](https://gist.github.com/talkingmoose/a16ca849416ce5ce89316bacd75fc91a) which can be used to install several different Microsoft applications and bundles, because Microsoft has a nice unified URL scheme.
|
||||
|
||||
At some point, earlier this year, I got frustrated at the number of scripts we were maintaining (or failing to). Also, my concern that most of the scripts weren't doing _any_ verification of the download was getting unbearable. So, I set out to write the one install script to rule them all...
|
||||
At some point, in 2018, Armin got frustrated at the number of scripts he was maintaining (or failing to). Also, his concern that most of the scripts weren’t doing _any_ verification of the download was getting unbearable. So, he set out to write _the one install script to rule them all…_
|
||||
|
||||
### Locally installed
|
||||
|
||||
So Armin made the version for Jamf Pro but universally for any MDM to adopt.
|
||||
|
||||
Søren looked at this, and wanted this approach to work in Mosyle and Addigy, and for these solutions we need Installomator to be locally installed on the Mac, and then the MDM can call this script from their scripts features. For some time Søren had a version of Installomator that was supplied with a notarized pkg, so it could be deployed as part of DEP or however was needed.
|
||||
|
||||
This has now been merged into Installomator, and with contributions of Isaac and Adam, new features and labels have been added more frequently.
|
||||
|
||||
## Goals
|
||||
|
||||
My goals for Installomator are:
|
||||
The goals for Installomator are:
|
||||
|
||||
- work with various common archive types
|
||||
- verify the downloaded archive or application
|
||||
- have a simple 'interface' to the admin
|
||||
- single script file so it can 'easily' be copied into a management system
|
||||
- have a simple ‘interface’ to the admin
|
||||
- single script file so it can ‘easily’ be copied into a management system
|
||||
- signed and notarized pkg-installer for local installation
|
||||
- extensible without deep scripting knowledge
|
||||
- work independently of a specific management system
|
||||
- no dependencies that may be removed from macOS in the future or are not pre-installed
|
||||
@@ -70,11 +124,11 @@ Installomator can work with the following common archive and installer types:
|
||||
- dmg: for the common 'drag app to /Applications' installation style
|
||||
- zip: the application is just compressed with zip or or tbz
|
||||
|
||||
When the download yields a pkg file, Installomator will run `installer` to install it on the current system.
|
||||
When the download yields a pkg file, Installomator will run `installer` to install it on the current system.
|
||||
|
||||
Applications in dmgs or zips will be copied to `/Applications` and their owner will be set to the current user, so the install works like a standard drag'n drop installation.
|
||||
Applications in dmgs or zips will be copied to `/Applications` and their owner will be set to the current user, so the install works like a standard drag'n drop installation. Owner can also be set to root/wheel.
|
||||
|
||||
(I consider it a disgrace, that Jamf, after nearly 20 years, _still_ cannot deal with 'drag'n drop installation dmgs' natively. It's not _that_ hard.)
|
||||
(I consider it a disgrace, that Jamf, after nearly 20 years, _still_ cannot deal with ‘drag’n drop installation dmgs natively. It’s not _that_ hard.)
|
||||
|
||||
### Verify the download
|
||||
|
||||
@@ -88,32 +142,49 @@ When used to install software, Installomator has a single argument: the label or
|
||||
|
||||
```
|
||||
./Installomator.sh firefox
|
||||
./Installomator.sh firefox LOGO=jamf BLOCKING_PROCESS_ACTION=tell_user_then_kill NOTIFY=all
|
||||
```
|
||||
|
||||
There is a debug mode and one other setting that can be controlled with variables in the code. This simplifies the actual use of the script from within a management system.
|
||||
There is a debug mode and other settings that can be controlled with variables in the code. This simplifies the actual use of the script from within a management system.
|
||||
|
||||
### Extensible
|
||||
|
||||
As of this writing, Installomator knows how to download and install more than 50 different applications. You can add more by adding a block to the _long_ `case` statement starting on line 160. Some of them are more elaborate, but most of them just need this information:
|
||||
As of this writing, Installomator knows how to download and install more than 364 different applications. You can add more by adding new labels to the `fragments`-folder. Below is an example of a label, and most of them (just) needs this information (not really "just" in this case, as we have to differentiate between arm64 and i386 versions for both `downloadURL` and `appNewVersion`):
|
||||
|
||||
```
|
||||
googlechrome)
|
||||
name="Google Chrome"
|
||||
type="dmg"
|
||||
googlechrome)
|
||||
name="Google Chrome"
|
||||
type="dmg"
|
||||
if [[ $(arch) != "i386" ]]; then
|
||||
printlog "Architecture: arm64 (not i386)"
|
||||
downloadURL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
|
||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac_arm64,stable/{print $3; exit}')
|
||||
else
|
||||
printlog "Architecture: i386"
|
||||
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac,stable/{print $3; exit}')
|
||||
fi
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
```
|
||||
|
||||
When you know how to extract these pieces of information from the application and/or download, then you can add an application to Installomator.
|
||||
|
||||
The script `buildLabel.sh` can help with the label creation. Just server the URL to the script, and it will try to figure out things and write out a label as output. See [Wiki Tutorials](https://github.com/Installomator/Installomator/wiki#tutorials).
|
||||
|
||||
Please note: Labels should be named in small caps, numbers 0-9, “-”, and “_”. No other characters allowed.
|
||||
|
||||
Actually labels are part of a case-statement, and must be formatted accordingly.
|
||||
|
||||
### Not specific to a management system
|
||||
|
||||
I wrote this script mainly for use with Jamf Pro, because that is what we use. For testing, you can run the script interactively from the command line. However, I have tried to keep anything that is specific to Jamf optional, or so flexible that it will work anywhere. Even if it does not work with your management system 'out of the box,' the adaptations should be straightforward.
|
||||
Armin wrote this script mainly for use with Jamf Pro, because that is what he used. For testing, you can run the script interactively from the command line. However, we have tried to keep anything that is specific to Jamf optional, or so flexible that it will work anywhere. Even if it does not work with your management system ‘out of the box’, the adaptations should be straightforward.
|
||||
|
||||
Not all MDMs can include the full script, for those MDMs it might be more useful to install it on the client machines, and run it from there. So a PKG to be installed on client Macs is also provided here.
|
||||
|
||||
### No dependencies
|
||||
|
||||
The script started out as a pure `sh` script, and when I needed arrays I 'switched' to `zsh`, because that is what [we can rely on being in macOS for the foreseeable future](https://scriptingosx.com/zsh). There are quite a few places where using python would have been easier and safer, but with the python 2 run-time being deprecated, that would have added a requirement for a Python 3 run-time to be installed. XML and JSON parsing would have been better with a tool like [scout](https://github.com/ABridoux/scout) or [jq](https://stedolan.github.io/jq/), but those would again require additional installations on the client before the script can run.
|
||||
The script started out as a pure `sh` script, and when arrays was needed it was ‘switched’ to `zsh`, because that is what [we can rely on being in macOS for the foreseeable future](https://scriptingosx.com/zsh). There are quite a few places where using python would have been easier and safer, but with the python 2 run-time being deprecated, that would have added a requirement for a Python 3 run-time to be installed. XML and JSON parsing would have been better with a tool like [scout](https://github.com/ABridoux/scout) or [jq](https://stedolan.github.io/jq/), but those would again require additional installations on the client before the script can run.
|
||||
|
||||
Keeping the script as a `zsh` allows you to paste it into your management system's interface (and disable the DEBUG mode) and use it without requiring any other installations.
|
||||
|
||||
@@ -127,41 +198,46 @@ The argument can be `version` or `longversion` which will print the script's ver
|
||||
|
||||
```
|
||||
> ./Installomator.sh version
|
||||
0.1
|
||||
2021-03-28 10:03:42 version ################## Start Installomator v. 0.5.0
|
||||
2021-03-28 10:03:42 version ################## version
|
||||
2021-03-28 10:03:42 version 0.5.0
|
||||
> ./Installomator.sh longversion
|
||||
Installomater: version 0.1 (20200506)
|
||||
2021-03-28 10:04:16 longversion ################## Start Installomator v. 0.5.0
|
||||
2021-03-28 10:04:16 longversion ################## longversion
|
||||
2021-03-28 10:04:16 longversion Installomater: version 0.5.0 (2021-03-28)
|
||||
```
|
||||
|
||||
Other than the version arguments, the argument can be any of the labels listed in the Labels.txt file. Each of the labels will download and install the latest version of the application, or suite of applications. Since the script will have to run the `installer` command or copy the application to the `/Applications` folder, it will have to be run as root.
|
||||
|
||||
```
|
||||
> sudo ./Installomator.sh desktoppr
|
||||
> sudo ./Installomator.sh desktoppr DEBUG=0
|
||||
```
|
||||
|
||||
(Since Jamf Pro always provides the mount point, computer name, and user name as the first three arguments for policy scripts, the script will use argument `$4` when there are more than three arguments.)
|
||||
|
||||
### Debug mode
|
||||
|
||||
There is a variable named `DEBUG` which is set in line 21 of the script. When `DEBUG` is set to `1` (default) no actions that would actually modify the current system are taken. This is useful for testing most of the actions in the script, but obviously not all of them.
|
||||
There is a variable named `DEBUG` which is set in line 21 of the script. When `DEBUG` is set to `1` (default) or `2` for a variation of debug, no actions that would actually modify the current system are taken. This is useful for testing most of the actions in the script, but obviously not all of them.
|
||||
|
||||
Also when the `DEBUG` variable is `1`, downloaded archives and extracted files will be written to the script's directory, rather than a temporary directory, which can make debugging easier.
|
||||
When the `DEBUG` variable is `1`, downloaded archives and extracted files will be written to the script's directory, rather than a temporary directory, which can make debugging easier.
|
||||
|
||||
_Always remember_ to change the `DEBUG` variable to `0` when deploying.
|
||||
When `DEBUG` variable is `2`, the temporary folder is created and downloaded and extracted files goes to that folder, as if not in DEBUG mode, but installation is still not done. On the other hand blocking processes are checked, the app is reopened if closed, and the user is notified.
|
||||
|
||||
### Use Installomator with Jamf Pro
|
||||
Debug mode 1 is useful to test the download and verification process without having to re-download and re-install an application or package on your system. Debug mode 2 is great for checking running processe and notifications.
|
||||
|
||||
In Jamf Pro, create a new 'Script' and paste the contents of `Installomator.sh` into the 'Script Contents' area. Under 'Options' you can change the parameter label for argument 4 to 'Application Label.'
|
||||
_Always remember_ to change the `DEBUG` variable to `0` when deploying. The installer PKG we provide has `DEBUG=0`.
|
||||
|
||||
Remember to set `DEBUG` to `0`.
|
||||
### Use Installomator with various MDM solutions
|
||||
|
||||
Then you can use the Installomator script in a policy and choose the application to install by setting the label for argument 4.
|
||||
In the wiki we have provided documentation on how Installomator is used in various MDM solution, like [Jamf Pro](https://github.com/Installomator/Installomator/wiki/MDM:-Jamf-Pro), [Mosyle](https://github.com/Installomator/Installomator/wiki/MDM:-Mosyle-(Business,-Fuse,-and-Manager)), and [Addigy](https://github.com/Installomator/Installomator/wiki/MDM:-Addigy).
|
||||
|
||||
## What it does
|
||||
|
||||
When it runs with a known label, the script will perform the following:
|
||||
|
||||
- when the application is running, prompt the user to quit or cancel
|
||||
- Check the version installed with the version online. Only continue if it's different
|
||||
- download the latest version from the vendor
|
||||
- when the application is running, prompt the user to quit or cancel (customizable)
|
||||
- dmg or zip archives:
|
||||
- extract the application and copy it to /Applications
|
||||
- change the owner of the application to the current user
|
||||
@@ -169,54 +245,108 @@ When it runs with a known label, the script will perform the following:
|
||||
- when necessary, extract the pkg from the enclosing archive
|
||||
- install the pkg with the `installer` tool
|
||||
- clean up the downloaded files
|
||||
- notify the user
|
||||
- notify the user (also customizable)
|
||||
|
||||
## Configuring the script
|
||||
|
||||
As of now there are two settings that are meant to configured when deploying the script.
|
||||
|
||||
### Debug mode
|
||||
|
||||
The first is the `DEBUG` variable. When this is set to `1` the script will _not_ perform any changes to the current system. In other words, no application will be copied to the target directory and no `installer` command be performed.
|
||||
|
||||
In addition, files will be downloaded and extracted to the Installomator project folder instead of a temporary directory and _not_ deleted when the script exits. Also archives will _not_ be re-downloaded when they already exist in the project folder. The repository's `.gitignore` file is set up to ignore the archive file extensions.
|
||||
|
||||
Debug mode is useful to test the download and verification process without having to re-download and re-install an application or package on your system.
|
||||
We have several default settings for certain behavior and notifications inside the script, but these can be customized when calling the script.
|
||||
|
||||
### Blocking Process actions
|
||||
|
||||
The `BLOCKING_PROCESS_ACTION` variable controls the behavior of the script when it finds a blocking process running.
|
||||
|
||||
There are four options:
|
||||
There are eight options:
|
||||
|
||||
- `ignore`: continue even when blocking processes are found
|
||||
- `silent_fail`: exit script without prompt or installation
|
||||
- `prompt_user`: show a user dialog for each blocking process found abort after three attempts to quit
|
||||
- `kill`: kill process without prompting or giving the user a chance to save
|
||||
- `ignore`: continue even when blocking processes are found.
|
||||
- `silent_fail`: Exit script without prompt or installation.
|
||||
- `prompt_user`: Show a user dialog for each blocking process found, user can choose "Quit and Update" or "Not Now". When "Quit and Update" is chosen, blocking process will be told to quit. Installomator will wait 30 seconds before checking again in case Save dialogs etc are being responded to. Installomator will abort if quitting after three tries does not succeed. "Not Now" will exit Installomator.
|
||||
- `prompt_user_then_kill`: show a user dialog for each blocking process found, user can choose "Quit and Update" or "Not Now". When "Quit and Update" is chosen, blocking process will be terminated. Installomator will abort if terminating after two tries does not succeed. "Not Now" will exit Installomator.
|
||||
- `prompt_user_loop`: Like prompt-user, but clicking "Not Now", will just wait an hour, and then it will ask again.
|
||||
WARNING! It might block the MDM agent on the machine, as the script will not exit, it will pause until the hour has passed, possibly blocking for other management actions in this time.
|
||||
- `tell_user`: (Default) User will be showed a notification about the important update, but user is only allowed to Quit and Continue, and then we ask the app to quit. This is default.
|
||||
- `tell_user_then_kill`: User will be showed a notification about the important update, but user is only allowed to Quit and Continue. If the quitting fails, the blocking processes will be terminated.
|
||||
- `kill`: kill process without prompting or giving the user a chance to save.
|
||||
|
||||
The default is `prompt_user`.
|
||||
If any process was closed, Installomator will try to open the app again, after the update process is done.
|
||||
|
||||
### Notification
|
||||
|
||||
The `NOTIFY` variable controls the notifications shown to the user. As of now, there are two options: `success` (default) and `silent`.
|
||||
The `NOTIFY` variable controls the notifications shown to the user. As of now, there are three options:
|
||||
|
||||
- `success`: notify the user after a successful install
|
||||
- `success`: (default) notify the user after a successful install
|
||||
- `silent`: no notifications
|
||||
- `all`: all notifications (great for Self Service installation)
|
||||
|
||||
### Logo
|
||||
|
||||
### Adding applications/label blocks
|
||||
The `LOGO` variable is used for the icon shown in dialog boxes. There are these options:
|
||||
|
||||
#### Required Variables
|
||||
- `appstore`: Icon is Apple App Store (default)
|
||||
- `jamf`: JAMF Pro
|
||||
- `mosyleb`: Mosyle Business
|
||||
- `mosylem`: Mosyle Manager (Education)
|
||||
- `addigy`: Addigy
|
||||
Path can also be set in the command call, and if file exists, it will be used, like `LOGO="/System/Applications/App\ Store.app/Contents/Resources/AppIcon.icns"` (spaces are escaped).
|
||||
|
||||
### App Store apps handling
|
||||
Default is `IGNORE_APP_STORE_APPS=no`
|
||||
__options:__
|
||||
- `no`: If installed app is from App Store (which include VPP installed apps) it will not be touched, no matter it's version (default)
|
||||
- `yes`: Replace App Store (and VPP) version of app and handle future updates using Installomator, even if latest version. Shouldn’t give any problems for the user in most cases. Known bad example: Slack will loose all settings.
|
||||
|
||||
### Owner of copied apps
|
||||
Default is `SYSTEMOWNER=0`
|
||||
__options:__
|
||||
- `0`: Current user will be owner of copied apps, just like if they installed it themselves (default).
|
||||
- `1`: root:wheel will be set on the copied app. Useful for shared machines.
|
||||
|
||||
### Install behavior (force installation)
|
||||
|
||||
Since we now make a version checking, and only installs the software if the version is different, an `INSTALL` variable can be used to force the installation:
|
||||
|
||||
- ` `: When not set, software is only installed if it is newer/different in version (default)
|
||||
- `force`: Install even if it’s the same version
|
||||
|
||||
### Re-opening of closed app
|
||||
|
||||
The `REOPEN` can be used to prevent the reopening of a closed app
|
||||
|
||||
- `yes`: (default) app will be reopened if it was closed
|
||||
- `no`: app not reopened
|
||||
|
||||
### Configuration from Arguments
|
||||
|
||||
You can provide a configuration variable, such as `DEBUG` or `NOTIFY` as an argument in the form `VAR=value`. For example:
|
||||
|
||||
```
|
||||
./Installomator.sh desktoppr DEBUG=0 NOTIFY=silent
|
||||
```
|
||||
|
||||
Providing variables this way will override any variables set in the script.
|
||||
|
||||
You can even provide _all_ the variables necessary for download and installation. Of course, without a label the argument parsing will fail, so I created a special label `valuesfromarguments` which only checks if the four required values are present:
|
||||
|
||||
```
|
||||
./Installomator.sh name=desktoppr type=pkg downloadURL=https://github.com/scriptingosx/desktoppr/releases/download/v0.3/desktoppr-0.3.pkg expectedTeamID=JME5BW3F3R valuesfromarguments
|
||||
```
|
||||
|
||||
The order of the variables and label is not relevant. But, when you provide more than one label, all but the _last_ label will be ignored.
|
||||
|
||||
Providing all the variables this way might be useful for certain downloads that have a customized URL for each vendor/customer (like customized TeamView or Watchman Monitoring) or are local downloads.
|
||||
|
||||
## Adding applications/label blocks
|
||||
|
||||
### Required Variables
|
||||
|
||||
The script requires four pieces of information to download and install an application:
|
||||
|
||||
```
|
||||
spotify)
|
||||
name="Spotify"
|
||||
type="dmg"
|
||||
downloadURL="https://download.scdn.co/Spotify.dmg"
|
||||
expectedTeamID="2FNC3A47ZF"
|
||||
;;
|
||||
spotify)
|
||||
name="Spotify"
|
||||
type="dmg"
|
||||
downloadURL="https://download.scdn.co/Spotify.dmg"
|
||||
expectedTeamID="2FNC3A47ZF"
|
||||
;;
|
||||
```
|
||||
|
||||
The four required variables are
|
||||
@@ -228,13 +358,31 @@ The display name of the installed application without the `.app` extensions.
|
||||
The type of installation. Possible values:
|
||||
- `dmg`: application in disk image file (drag'n drop installation)
|
||||
- `pkg`: flat pkg download
|
||||
- `zip`: application in zip archive (`zip` or `tbz` extension)
|
||||
- `zip`: application in zip archive (`zip` extension)
|
||||
- `tbz`: application in tbz archive (`tbz` extension)
|
||||
- `pkgInDmg`: a pkg file inside a disk image
|
||||
- `pkgInZip`: a pkg file inside a zip
|
||||
- `appInDmgInZip`: an app in a dmg file that has been zip'ed
|
||||
|
||||
- `downloadURL`:
|
||||
The URL from which to download the archive.
|
||||
The URL can be generated by a series of commands, for example when you need to parse an xml file for the latest URL. (See `bbedit`, `desktoppr`, or `omnigraffle` for examples.)
|
||||
Sometimes version differs between Intel and Apple Silicon versions. (See `brave`, `obsidian`, `omnidisksweeper`, or `notion`).
|
||||
|
||||
- `curlOptions`: (array, optional)
|
||||
Options to the `curl` command, needed for `curl` to be able to download the software.
|
||||
Usually used for adding extra headers that some servers need in order to serve the file.
|
||||
`curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" )`
|
||||
(See “mocha”-labels, for examples on labels, and `buildLabel.sh` for header-examples.)
|
||||
|
||||
- `appNewVersion` (optional, but recommended):
|
||||
Version of the downloaded software.
|
||||
If given, it will be compared to installed version, to see if download is different.
|
||||
It does not check for newer or not, only different.
|
||||
Not always easy to figure out how to make this. Sometimes this is listed on the downloads page, sometimes in other places. And how can we isolate it in a genral manner? (See `abstract`, `bbedit`, `brave`, `desktoppr`, `googlechrome`, or `omnidisksweeper`).
|
||||
|
||||
- `packageID` (optional, but recommended for pkgs without an app)
|
||||
This variable is for pkg bundle IDs. Very usefull if a pkg only install command line tools, or the like that does not install an app. (See label `desktoppr`, `golang`, `installomator_st`, `odrive`, or `teamviewerhost`).
|
||||
|
||||
- `expectedTeamID`:
|
||||
The 10-character Developer Team ID with which the application or pkg is signed and notarized.
|
||||
@@ -244,11 +392,10 @@ The 10-character Developer Team ID with which the application or pkg is signed a
|
||||
- Applications (in dmgs or zips)
|
||||
`spctl -a -vv /Applications/BBEdit.app`
|
||||
|
||||
- Pkgs
|
||||
- Installation Packages (pkg)
|
||||
`spctl -a -vv -t install ~/Downloads/desktoppr-0.2.pkg`
|
||||
|
||||
|
||||
#### Optional Variables
|
||||
### Optional Variables
|
||||
|
||||
Depending on the application or pkg there are a few more variables you can or need to set. Many of these are derived from the required variables, but may need to be set manually if those derived values do not work.
|
||||
|
||||
@@ -259,12 +406,13 @@ Depending on the application or pkg there are a few more variables you can or ne
|
||||
- `appName`: (optional)
|
||||
File name of the app bundle in the dmg to verify and copy (include the `.app`).
|
||||
When not given, the `appName` is set to `$name.app`.
|
||||
This is also the name of the app that will get reopned, if we closed any `blockingProcesses` (see further down)
|
||||
|
||||
- `targetDir`: (optional)
|
||||
dmg or zip:
|
||||
Applications will be copied to this directory.
|
||||
Default value is '`/Applications`' for dmg and zip installations.
|
||||
pkg:
|
||||
pkg:
|
||||
`targetDir` is used as the install-location. Default is '`/`'.
|
||||
|
||||
- `blockingProcesses`: (optional)
|
||||
@@ -286,26 +434,35 @@ Depending on the application or pkg there are a few more variables you can or ne
|
||||
`$updateTool $updateArguments`
|
||||
Will be run instead of of downloading and installing a complete new version.
|
||||
Use this when the `updateTool` does differential and optimized downloads.
|
||||
e.g. `msupdate` (see microsoft installations)
|
||||
e.g. `msupdate` (see various Microsoft installations).
|
||||
|
||||
- `updateToolRunAsCurrentUser`:
|
||||
When this variable is set (any value), `$updateTool` will be run as the current user. Default is unset and
|
||||
When this variable is set (any value), `$updateTool` will be run as the current user. Default is unset and
|
||||
|
||||
- `CLIInstaller`:
|
||||
- `CLIArguments`:
|
||||
If the downloaded dmg is actually an installer that we can call using CLI, we can use these two variables for what to call.
|
||||
We need to define `name` for the installed app (to be version checked), as well as `installerTool` for the installer app (if named differently that `name`. Installomator will add the path to the folder/disk image with the binary, and it will be called like this:
|
||||
`$CLIInstaller $CLIArguments`
|
||||
For most installations `CLIInstaller` should contain the `installerTool` for the CLI call (if it’s the same).
|
||||
We can support a whole range of other software titles by implementing this.
|
||||
See label adobecreativeclouddesktop.
|
||||
|
||||
- `installerTool`:
|
||||
Introduced as part of `CLIInstaller`. If the installer in the DMG or ZIP is named differently than the installed app, then this variable can be used to name the installer that should be located after mounting/expanding the downloaded archive.
|
||||
See label adobecreativeclouddesktop
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### What if the latest version of the app is already installed?
|
||||
|
||||
Short answer: Installomator will re-download and re-install the latest over the existing installation.
|
||||
Short answer: That depends on if labels will know what the latest version will be.
|
||||
|
||||
Longer answer:
|
||||
|
||||
Installomator will try to find a currently installed app to log the version. When Installomator finds an existing app (any version) and the `updateTool` variable is set, then Installomator will _not_ download and install, but run the `updateTool` instead.
|
||||
|
||||
However, there is no simple generic method to actually determine the latest version of an application or installer.
|
||||
|
||||
We deploy Installomator usually for user initiated installations from Self Service, so re-installs don't really 'hurt' and may be a useful troubleshooting step.
|
||||
|
||||
When you want to have automated installations, you can use smart groups based on the app version to limit excessive re-installations.
|
||||
- Labels without this will re-download and re-install the latest over the existing installation.
|
||||
- Labels with this info will only install the app if the version is different than the one installed.
|
||||
- Labels that can use update tool will use that for the update (if the version is different)
|
||||
|
||||
### Why don't you just use `autopkg install`?
|
||||
|
||||
@@ -335,7 +492,7 @@ Please don't misunderstand this as me saying that AutoPkg is a bad or poorly des
|
||||
|
||||
But it is not suited as a client install automation tool.
|
||||
|
||||
### Why don't you just use brew?
|
||||
### Why don't you just use brew or MacPorts?
|
||||
|
||||
Read the explanation for `autopkg`, pretty much the same applies for `brew`, i.e. While it is useful on a single Mac, it is a un-manageable mess when you think about deploying and managing on a fleet of computers.
|
||||
Read the explanation for `autopkg`, pretty much the same applies for `brew`, i.e. while it is useful on a single Mac, it is a un-manageable mess when you think about deploying and managing on a fleet of computers.
|
||||
|
||||
|
||||
1
assemble.sh
Symbolic link
1
assemble.sh
Symbolic link
@@ -0,0 +1 @@
|
||||
utils/assemble.sh
|
||||
@@ -1,90 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
downloadURL=${1?:"need to provide a download URL"}
|
||||
|
||||
# Note: this tool _very_ experimental and does not work in many cases
|
||||
|
||||
|
||||
# create temporary working directory
|
||||
tmpDir=$(dirname $0 )
|
||||
|
||||
# change directory to temporary working directory
|
||||
echo "Changing directory to $tmpDir"
|
||||
if ! cd "$tmpDir"; then
|
||||
echo "error changing directory $tmpDir"
|
||||
#rm -Rf "$tmpDir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# download the dmg
|
||||
echo "Downloading $downloadURL"
|
||||
if ! curl --location --fail --silent "$downloadURL" --remote-header-name --remote-name; then
|
||||
echo "error downloading $downloadURL"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
archivePath=$(find $tmpDir -print )
|
||||
archiveName=${archivePath##*/}
|
||||
name=${archiveName%.*}
|
||||
archiveExt=${archiveName##*.}
|
||||
identifier=$(echo $name | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
if [ "$archiveExt" = "pkg" ]; then
|
||||
teamID=$(spctl -a -vv -t install "$archiveName" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' )
|
||||
elif [ "$archiveExt" = "dmg" ]; then
|
||||
# mount the dmg
|
||||
echo "Mounting $archiveName"
|
||||
if ! dmgmount=$(echo "Y"$'\n' | hdiutil attach "$archiveName" -nobrowse -readonly | tail -n 1 | cut -c 54- ); then
|
||||
echo "Error mounting $archiveName"
|
||||
exit 3
|
||||
fi
|
||||
echo "Mounted: $dmgmount"
|
||||
# check if app exists
|
||||
|
||||
appPath=$(find "$dmgmount" -name "*.app" -maxdepth 1 -print )
|
||||
appName=${appPath##*/}
|
||||
|
||||
# verify with spctl
|
||||
echo "Verifying: $appPath"
|
||||
if ! teamID=$(spctl -a -vv "$appPath" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' ); then
|
||||
echo "Error verifying $appPath"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
hdiutil detach "$dmgmount"
|
||||
elif [ "$archiveExt" = "zip" ] || [ "$archiveExt" = "tbz" ]; then
|
||||
# unzip the archive
|
||||
tar -xf "$archiveName"
|
||||
|
||||
# check if app exists
|
||||
appPath=$(find "$tmpDir" -name "*.app" -maxdepth 2 -print )
|
||||
appName=${appPath##*/}
|
||||
# verify with spctl
|
||||
echo "Verifying: $appPath"
|
||||
if ! teamID=$(spctl -a -vv "$appPath" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' ); then
|
||||
echo "Error verifying $appPath"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
echo
|
||||
echo " $identifier)"
|
||||
echo " name=\"$name\""
|
||||
echo " type=\"$archiveExt\""
|
||||
echo " downloadURL=\"$downloadURL\""
|
||||
echo " expectedTeamID=\"$teamID\""
|
||||
if [ -n "$appName" ] && [ "$appName" != "${name}.app" ]; then
|
||||
echo " appName=\"$appName\""
|
||||
fi
|
||||
echo " ;;"
|
||||
echo
|
||||
|
||||
#if [ -e "${tmpDir}" ]; then
|
||||
# #echo "deleting tmp dir"
|
||||
# rm -rf "${tmpDir}"
|
||||
#fi
|
||||
|
||||
exit 0
|
||||
139
fragments/arguments.sh
Normal file
139
fragments/arguments.sh
Normal file
@@ -0,0 +1,139 @@
|
||||
# MARK: check minimal macOS requirement
|
||||
autoload is-at-least
|
||||
|
||||
installedOSversion=$(sw_vers -productVersion)
|
||||
if ! is-at-least 10.14 $installedOSversion; then
|
||||
printlog "Installomator requires at least macOS 10.14 Mojave." ERROR
|
||||
exit 98
|
||||
fi
|
||||
|
||||
|
||||
# MARK: argument parsing
|
||||
if [[ $# -eq 0 ]]; then
|
||||
if [[ -z $label ]]; then # check if label is set inside script
|
||||
printlog "no label provided, printing labels" REQ
|
||||
grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "$0" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
||||
#grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "${labelFile}" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
||||
exit 0
|
||||
fi
|
||||
elif [[ $1 == "/" ]]; then
|
||||
# jamf uses sends '/' as the first argument
|
||||
printlog "shifting arguments for Jamf" REQ
|
||||
shift 3
|
||||
fi
|
||||
|
||||
while [[ -n $1 ]]; do
|
||||
if [[ $1 =~ ".*\=.*" ]]; then
|
||||
# if an argument contains an = character, send it to eval
|
||||
printlog "setting variable from argument $1" INFO
|
||||
eval $1
|
||||
else
|
||||
# assume it's a label
|
||||
label=$1
|
||||
fi
|
||||
# shift to next argument
|
||||
shift 1
|
||||
done
|
||||
|
||||
# lowercase the label
|
||||
label=${label:l}
|
||||
|
||||
# separate check for 'version' in order to print plain version number without any other information
|
||||
if [[ $label == "version" ]]; then
|
||||
echo "$VERSION"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# MARK: Logging
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
|
||||
# Check if we're in debug mode, if so then set logging to DEBUG, otherwise default to INFO
|
||||
# if no log level is specified.
|
||||
if [[ $DEBUG -ne 0 ]]; then
|
||||
LOGGING=DEBUG
|
||||
elif [[ -z $LOGGING ]]; then
|
||||
LOGGING=INFO
|
||||
datadogLoggingLevel=INFO
|
||||
fi
|
||||
|
||||
# Associate logging levels with a numerical value so that we are able to identify what
|
||||
# should be removed. For example if the LOGGING=ERROR only printlog statements with the
|
||||
# level REQ and ERROR will be displayed. LOGGING=DEBUG will show all printlog statements.
|
||||
# If a printlog statement has no level set it's automatically assigned INFO.
|
||||
|
||||
declare -A levels=(DEBUG 0 INFO 1 WARN 2 ERROR 3 REQ 4)
|
||||
|
||||
# If we are able to detect an MDM URL (Jamf Pro) or another identifier for a customer/instance we grab it here, this is useful if we're centrally logging multiple MDM instances.
|
||||
if [[ -f /Library/Preferences/com.jamfsoftware.jamf.plist ]]; then
|
||||
mdmURL=$(defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url)
|
||||
elif [[ -n "$MDMProfileName" ]]; then
|
||||
mdmURL=$(sudo profiles show | grep -A3 "$MDMProfileName" | sed -n -e 's/^.*organization: //p')
|
||||
else
|
||||
mdmURL="Unknown"
|
||||
fi
|
||||
|
||||
# Generate a session key for this run, this is useful to idenify streams when we're centrally logging.
|
||||
SESSION=$RANDOM
|
||||
|
||||
# Mark: START
|
||||
printlog "################## Start Installomator v. $VERSION, date $VERSIONDATE" REQ
|
||||
printlog "################## Version: $VERSION" INFO
|
||||
printlog "################## Date: $VERSIONDATE" INFO
|
||||
printlog "################## $label" INFO
|
||||
|
||||
# Check for DEBUG mode
|
||||
if [[ $DEBUG -gt 0 ]]; then
|
||||
printlog "DEBUG mode $DEBUG enabled." DEBUG
|
||||
fi
|
||||
|
||||
# How we get version number from app
|
||||
if [[ -z $versionKey ]]; then
|
||||
versionKey="CFBundleShortVersionString"
|
||||
fi
|
||||
|
||||
# get current user
|
||||
currentUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
|
||||
|
||||
# MARK: check for root
|
||||
if [[ "$(whoami)" != "root" && "$DEBUG" -eq 0 ]]; then
|
||||
# not running as root
|
||||
cleanupAndExit 6 "not running as root, exiting" ERROR
|
||||
fi
|
||||
|
||||
|
||||
# check Swift Dialog presence and version
|
||||
DIALOG_CMD="/usr/local/bin/dialog"
|
||||
|
||||
if [[ ! -x $DIALOG_CMD ]]; then
|
||||
# Swift Dialog is not installed, clear cmd file variable to ignore
|
||||
printlog "SwiftDialog is not installed, clear cmd file var"
|
||||
DIALOG_CMD_FILE=""
|
||||
fi
|
||||
|
||||
# MARK: labels in case statement
|
||||
case $label in
|
||||
longversion)
|
||||
# print the script version
|
||||
printlog "Installomater: version $VERSION ($VERSIONDATE)" REQ
|
||||
exit 0
|
||||
;;
|
||||
valuesfromarguments)
|
||||
if [[ -z $name ]]; then
|
||||
printlog "need to provide 'name'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $type ]]; then
|
||||
printlog "need to provide 'type'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $downloadURL ]]; then
|
||||
printlog "need to provide 'downloadURL'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $expectedTeamID ]]; then
|
||||
printlog "need to provide 'expectedTeamID'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
# label descriptions start here
|
||||
6
fragments/broken/brokenappname.sh
Normal file
6
fragments/broken/brokenappname.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
brokenappname)
|
||||
name="brokenapp"
|
||||
type="dmg"
|
||||
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
6
fragments/broken/brokendownloadurl.sh
Normal file
6
fragments/broken/brokendownloadurl.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
brokendownloadurl)
|
||||
name="Google Chrome"
|
||||
type="dmg"
|
||||
downloadURL="https://broken.com/broken.dmg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
6
fragments/broken/brokenteamid.sh
Normal file
6
fragments/broken/brokenteamid.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
brokenteamid)
|
||||
name="Google Chrome"
|
||||
type="dmg"
|
||||
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
||||
expectedTeamID="broken"
|
||||
;;
|
||||
10
fragments/disabled/fontforge.sh
Normal file
10
fragments/disabled/fontforge.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
fontforge)
|
||||
# FontForge Not signed
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="FontForge"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit fontforge fontforge)
|
||||
appNewVersion=$(versionFromGit fontforge fontforge)
|
||||
expectedTeamID=""
|
||||
;;
|
||||
12
fragments/disabled/notifier.sh
Normal file
12
fragments/disabled/notifier.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
notifier)
|
||||
# not signed
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="dataJAR Notifier"
|
||||
type="pkg"
|
||||
#packageID="uk.co.dataJAR.Notifier" # Version 2.2.3 was actually "uk.co.dataJAR.Notifier-2.2.3" so unusable
|
||||
downloadURL=$(downloadURLFromGit dataJAR Notifier)
|
||||
appNewVersion=$(versionFromGit dataJAR Notifier)
|
||||
expectedTeamID=""
|
||||
blockingProcesses=( "Notifier" )
|
||||
;;
|
||||
8
fragments/disabled/parallels.sh
Normal file
8
fragments/disabled/parallels.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
parallels)
|
||||
# This downloads an installer app, so not really useful here
|
||||
name="Parallels Desktop"
|
||||
type="dmg"
|
||||
downloadURL="https://parallels.com/directdownload/pd15/"
|
||||
appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i ^location | tail -1 | cut -d "/" -f6)
|
||||
expectedTeamID="4C6364ACXT"
|
||||
;;
|
||||
10
fragments/disabled/powershell-lts.sh
Normal file
10
fragments/disabled/powershell-lts.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
powershell-lts)
|
||||
#NOTE: powershell installers are not notarized
|
||||
# credit: Tadayuki Onishi (@kenchan0130)
|
||||
name="PowerShell"
|
||||
type="pkg"
|
||||
downloadURL=$(curl -fs "https://api.github.com/repos/Powershell/Powershell/releases/latest" \
|
||||
| awk -F '"' '/browser_download_url/ && /pkg/ { print $4 }' | grep lts)
|
||||
expectedTeamID="UBF8T346G9"
|
||||
;;
|
||||
10
fragments/disabled/powershell.sh
Normal file
10
fragments/disabled/powershell.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
powershell)
|
||||
#NOTE: powershell installers are not notarized
|
||||
# credit: Tadayuki Onishi (@kenchan0130)
|
||||
name="PowerShell"
|
||||
type="pkg"
|
||||
downloadURL=$(curl -fs "https://api.github.com/repos/Powershell/Powershell/releases/latest" \
|
||||
| awk -F '"' '/browser_download_url/ && /pkg/ { print $4 }' | grep -v lts )
|
||||
expectedTeamID="UBF8T346G9"
|
||||
;;
|
||||
10
fragments/disabled/vmwarefusion.sh
Normal file
10
fragments/disabled/vmwarefusion.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
vmwarefusion)
|
||||
#TODO: vmwarefusion installation process needs testing
|
||||
# credit: Erik Stam (@erikstam)
|
||||
name="VMware Fusion"
|
||||
type="dmg"
|
||||
downloadURL="https://www.vmware.com/go/getfusion"
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*Fusion-([0-9.]*)-.*/\1/g' )
|
||||
expectedTeamID="EG7KH642X6"
|
||||
;;
|
||||
9
fragments/disabled/wickrme.sh
Normal file
9
fragments/disabled/wickrme.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
wickrme)
|
||||
# Label not working, haven't found a solution
|
||||
name="WickrMe"
|
||||
printlog "Label for $name broken in test" WARN
|
||||
type="dmg"
|
||||
downloadURL=$( curl -fs https://me-download.wickr.com/api/download/me/download/mac | tr '"' '\n' | grep -e '^https://' )
|
||||
appNewVersion=$( echo ${downloadURL} | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="W8RC3R952A"
|
||||
;;
|
||||
9
fragments/disabled/wickrpro.sh
Normal file
9
fragments/disabled/wickrpro.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
wickrpro)
|
||||
# Label not working, haven't found a solution
|
||||
name="WickrPro"
|
||||
printlog "Label for $name broken in test" WARN
|
||||
type="dmg"
|
||||
downloadURL=$( curl -fs https://me-download.wickr.com/api/download/pro/download/mac | tr '"' '\n' | grep -e '^https://' )
|
||||
appNewVersion=$( echo ${downloadURL} | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="W8RC3R952A"
|
||||
;;
|
||||
13
fragments/disabled/wordmat.sh
Normal file
13
fragments/disabled/wordmat.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
wordmat)
|
||||
# WordMat currently not signed
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="WordMat"
|
||||
type="pkg"
|
||||
packageID="com.eduap.pkg.WordMat"
|
||||
downloadURL=$(downloadURLFromGit Eduap-com WordMat)
|
||||
#downloadURL=$(curl -fs "https://api.github.com/repos/Eduap-com/WordMat/releases/latest" | awk -F '"' "/browser_download_url/ && /pkg/ && ! /sig/ && ! /CLI/ && ! /sha256/ { print \$4 }")
|
||||
appNewVersion=$(versionFromGit Eduap-com WordMat)
|
||||
#curl -fs "https://api.github.com/repos/Eduap-com/WordMat/releases/latest" | grep tag_name | cut -d '"' -f 4 | sed 's/[^0-9\.]//g'
|
||||
expectedTeamID=""
|
||||
;;
|
||||
8
fragments/disabled/wwdcformac.sh
Normal file
8
fragments/disabled/wwdcformac.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
wwdcformac)
|
||||
#this label looks like software/site is gone
|
||||
name="WWDC"
|
||||
type="zip"
|
||||
downloadURL="https://cdn.wwdc.io/WWDC_latest.zip"
|
||||
expectedTeamID="8C7439RJLG"
|
||||
;;
|
||||
1031
fragments/functions.sh
Normal file
1031
fragments/functions.sh
Normal file
File diff suppressed because it is too large
Load Diff
324
fragments/header.sh
Normal file
324
fragments/header.sh
Normal file
@@ -0,0 +1,324 @@
|
||||
#!/bin/zsh
|
||||
label="" # if no label is sent to the script, this will be used
|
||||
|
||||
# Installomator
|
||||
#
|
||||
# Downloads and installs Applications
|
||||
# 2020-2021 Installomator
|
||||
#
|
||||
# inspired by the download scripts from William Smith and Sander Schram
|
||||
#
|
||||
# Contributers:
|
||||
# Armin Briegel - @scriptingosx
|
||||
# Isaac Ordonez - @issacatmann
|
||||
# Søren Theilgaard - @Theile
|
||||
# Adam Codega - @acodega
|
||||
#
|
||||
# with contributions from many others
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# NOTE: adjust these variables:
|
||||
|
||||
# set to 0 for production, 1 or 2 for debugging
|
||||
# while debugging, items will be downloaded to the parent directory of this script
|
||||
# also no actual installation will be performed
|
||||
# debug mode 1 will download to the directory the script is run in, but will not check the version
|
||||
# debug mode 2 will download to the temp directory, check for blocking processes, check the version, but will not install anything or remove the current version
|
||||
DEBUG=1
|
||||
|
||||
# notify behavior
|
||||
NOTIFY=success
|
||||
# options:
|
||||
# - success notify the user on success
|
||||
# - silent no notifications
|
||||
# - all all notifications (great for Self Service installation)
|
||||
|
||||
# behavior when blocking processes are found
|
||||
BLOCKING_PROCESS_ACTION=tell_user
|
||||
# options:
|
||||
# - ignore continue even when blocking processes are found
|
||||
# - quit app will be told to quit nicely if running
|
||||
# - quit_kill told to quit twice, then it will be killed
|
||||
# Could be great for service apps if they do not respawn
|
||||
# - silent_fail exit script without prompt or installation
|
||||
# - prompt_user show a user dialog for each blocking process found,
|
||||
# user can choose "Quit and Update" or "Not Now".
|
||||
# When "Quit and Update" is chosen, blocking process
|
||||
# will be told to quit. Installomator will wait 30 seconds
|
||||
# before checking again in case Save dialogs etc are being responded to.
|
||||
# Installomator will abort if quitting after three tries does not succeed.
|
||||
# "Not Now" will exit Installomator.
|
||||
# - prompt_user_then_kill
|
||||
# show a user dialog for each blocking process found,
|
||||
# user can choose "Quit and Update" or "Not Now".
|
||||
# When "Quit and Update" is chosen, blocking process
|
||||
# will be terminated. Installomator will abort if terminating
|
||||
# after two tries does not succeed. "Not Now" will exit Installomator.
|
||||
# - prompt_user_loop
|
||||
# Like prompt-user, but clicking "Not Now", will just wait an hour,
|
||||
# and then it will ask again.
|
||||
# WARNING! It might block the MDM agent on the machine, as
|
||||
# the script will not exit, it will pause until the hour has passed,
|
||||
# possibly blocking for other management actions in this time.
|
||||
# - tell_user User will be showed a notification about the important update,
|
||||
# but user is only allowed to Quit and Continue, and then we
|
||||
# ask the app to quit. This is default.
|
||||
# - tell_user_then_kill
|
||||
# User will be showed a notification about the important update,
|
||||
# but user is only allowed to Quit and Continue. If the quitting fails,
|
||||
# the blocking processes will be terminated.
|
||||
# - kill kill process without prompting or giving the user a chance to save
|
||||
|
||||
|
||||
# logo-icon used in dialog boxes if app is blocking
|
||||
LOGO=appstore
|
||||
# options:
|
||||
# - appstore Icon is Apple App Store (default)
|
||||
# - jamf JAMF Pro
|
||||
# - mosyleb Mosyle Business
|
||||
# - mosylem Mosyle Manager (Education)
|
||||
# - addigy Addigy
|
||||
# - microsoft Microsoft Endpoint Manager (Intune)
|
||||
# - ws1 Workspace ONE (AirWatch)
|
||||
# path can also be set in the command call, and if file exists, it will be used.
|
||||
# Like 'LOGO="/System/Applications/App\ Store.app/Contents/Resources/AppIcon.icns"'
|
||||
# (spaces have to be escaped).
|
||||
|
||||
|
||||
# App Store apps handling
|
||||
IGNORE_APP_STORE_APPS=no
|
||||
# options:
|
||||
# - no If the installed app is from App Store (which include VPP installed apps)
|
||||
# it will not be touched, no matter its version (default)
|
||||
# - yes Replace App Store (and VPP) version of the app and handle future
|
||||
# updates using Installomator, even if latest version.
|
||||
# Shouldn’t give any problems for the user in most cases.
|
||||
# Known bad example: Slack will lose all settings.
|
||||
|
||||
# Owner of copied apps
|
||||
SYSTEMOWNER=0
|
||||
# options:
|
||||
# - 0 Current user will be owner of copied apps, just like if they
|
||||
# installed it themselves (default).
|
||||
# - 1 root:wheel will be set on the copied app.
|
||||
# Useful for shared machines.
|
||||
|
||||
# install behavior
|
||||
INSTALL=""
|
||||
# options:
|
||||
# - When not set, the software will only be installed
|
||||
# if it is newer/different in version
|
||||
# - force Install even if it’s the same version
|
||||
|
||||
|
||||
# Re-opening of closed app
|
||||
REOPEN="yes"
|
||||
# options:
|
||||
# - yes App will be reopened if it was closed
|
||||
# - no App not reopened
|
||||
|
||||
# Only let Installomator return the name of the label
|
||||
# RETURN_LABEL_NAME=0
|
||||
# options:
|
||||
# - 1 Installomator will return the name of the label and exit, so last line of
|
||||
# output will be that name. When Installomator is locally installed and we
|
||||
# use DEPNotify, then DEPNotify can present a more nice name to the user,
|
||||
# instead of just the label name.
|
||||
|
||||
|
||||
# Interrupt Do Not Disturb (DND) full screen apps
|
||||
INTERRUPT_DND="yes"
|
||||
# options:
|
||||
# - yes Script will run without checking for DND full screen apps.
|
||||
# - no Script will exit when an active DND full screen app is detected.
|
||||
|
||||
# Comma separated list of app names to ignore when evaluating DND
|
||||
IGNORE_DND_APPS=""
|
||||
# example that will ignore browsers when evaluating DND:
|
||||
# IGNORE_DND_APPS="firefox,Google Chrome,Safari,Microsoft Edge,Opera,Amphetamine,caffeinate"
|
||||
|
||||
|
||||
# Swift Dialog integration
|
||||
|
||||
# These variables will allow Installomator to communicate progress with Swift Dialog
|
||||
# https://github.com/bartreardon/swiftDialog
|
||||
|
||||
# This requires Swift Dialog 2.11.2 or higher.
|
||||
|
||||
DIALOG_CMD_FILE=""
|
||||
# When this variable is set, Installomator will write Swift Dialog commands to this path.
|
||||
# Installomator will not launch Swift Dialog. The process calling Installomator will have
|
||||
# launch and configure Swift Dialog to listen to this file.
|
||||
# See `MDM/swiftdialog_example.sh` for an example.
|
||||
|
||||
DIALOG_LIST_ITEM_NAME=""
|
||||
# When this variable is set, progress for downloads and installs will be sent to this
|
||||
# listitem.
|
||||
# When the variable is unset, progress will be sent to Swift Dialog's main progress bar.
|
||||
|
||||
|
||||
|
||||
# NOTE: How labels work
|
||||
|
||||
# Each workflow label needs to be listed in the case statement below.
|
||||
# for each label these variables can be set:
|
||||
#
|
||||
# - name: (required)
|
||||
# Name of the installed app.
|
||||
# This is used to derive many of the other variables.
|
||||
#
|
||||
# - type: (required)
|
||||
# The type of the installation. Possible values:
|
||||
# - dmg
|
||||
# - pkg
|
||||
# - zip
|
||||
# - tbz
|
||||
# - pkgInDmg
|
||||
# - pkgInZip
|
||||
# - appInDmgInZip
|
||||
# - updateronly This last one is for labels that should only run an updateTool (see below)
|
||||
#
|
||||
# - packageID: (optional)
|
||||
# The package ID of a pkg
|
||||
# If given, will be used to find the version of installed software, instead of searching for an app.
|
||||
# Usefull if a pkg does not install an app.
|
||||
# See label installomator_st
|
||||
#
|
||||
# - downloadURL: (required)
|
||||
# URL to download the dmg.
|
||||
# Can be generated with a series of commands (see BBEdit for an example).
|
||||
#
|
||||
# - curlOptions: (array, optional)
|
||||
# Options to the curl command, needed for curl to be able to download the software.
|
||||
# Usually used for adding extra headers that some servers need in order to serve the file.
|
||||
# curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" )
|
||||
# (See “mocha”-labels, for examples on labels, and buildLabel.sh for header-examples.)
|
||||
#
|
||||
# - appNewVersion: (optional)
|
||||
# Version of the downloaded software.
|
||||
# If given, it will be compared to the installed version, to see if the download is different.
|
||||
# It does not check for newer or not, only different.
|
||||
#
|
||||
# - versionKey: (optional)
|
||||
# How we get version number from app. Possible values:
|
||||
# - CFBundleShortVersionString
|
||||
# - CFBundleVersion
|
||||
# Not all software titles uses fields the same.
|
||||
# See Opera label.
|
||||
#
|
||||
# - appCustomVersion(){}: (optional function)
|
||||
# This function can be added to your label, if a specific custom
|
||||
# mechanism hs to be used for getting the installed version.
|
||||
# See labels zulujdk11, zulujdk13, zulujdk15
|
||||
#
|
||||
# - expectedTeamID: (required)
|
||||
# 10-digit developer team ID.
|
||||
# Obtain the team ID by running:
|
||||
#
|
||||
# - Applications (in dmgs or zips)
|
||||
# spctl -a -vv /Applications/BBEdit.app
|
||||
#
|
||||
# - Pkgs
|
||||
# spctl -a -vv -t install ~/Downloads/desktoppr-0.2.pkg
|
||||
#
|
||||
# The team ID is the ten-digit ID at the end of the line starting with 'origin='
|
||||
#
|
||||
# - archiveName: (optional)
|
||||
# The name of the downloaded file.
|
||||
# When not given the archiveName is derived from the $name.
|
||||
# Note: This has to be defined BEFORE calling downloadURLFromGit or
|
||||
# versionFromGit functions in the label.
|
||||
#
|
||||
# - appName: (optional)
|
||||
# File name of the app bundle in the dmg to verify and copy (include .app).
|
||||
# When not given, the appName is derived from the $name.
|
||||
#
|
||||
# - targetDir: (optional)
|
||||
# dmg or zip:
|
||||
# Applications will be copied to this directory.
|
||||
# Default value is '/Applications' for dmg and zip installations.
|
||||
# pkg:
|
||||
# targetDir is used as the install-location. Default is '/'.
|
||||
#
|
||||
# - blockingProcesses: (optional)
|
||||
# Array of process names that will block the installation or update.
|
||||
# If no blockingProcesses array is given the default will be:
|
||||
# blockingProcesses=( $name )
|
||||
# When a package contains multiple applications, _all_ should be listed, e.g:
|
||||
# blockingProcesses=( "Keynote" "Pages" "Numbers" )
|
||||
# When a workflow has no blocking processes, use
|
||||
# blockingProcesses=( NONE )
|
||||
#
|
||||
# - pkgName: (optional, only used for pkgInDmg, dmgInZip, and appInDmgInZip)
|
||||
# File name or path to the pkg/dmg file _inside_ the dmg or zip.
|
||||
# When not given the pkgName is derived from the $name
|
||||
#
|
||||
# - updateTool:
|
||||
# - updateToolArguments:
|
||||
# When Installomator detects an existing installation of the application,
|
||||
# and the updateTool variable is set
|
||||
# $updateTool $updateArguments
|
||||
# Will be run instead of of downloading and installing a complete new version.
|
||||
# Use this when the updateTool does differential and optimized downloads.
|
||||
# e.g. msupdate on various Microsoft labels
|
||||
#
|
||||
# - updateToolRunAsCurrentUser:
|
||||
# When this variable is set (any value), $updateTool will be run as the current user.
|
||||
#
|
||||
# - CLIInstaller:
|
||||
# - CLIArguments:
|
||||
# If the downloaded dmg is an installer that we can call using CLI, we can
|
||||
# use these two variables for what to call.
|
||||
# We need to define `name` for the installed app (to be version checked), as well as
|
||||
# `installerTool` for the installer app (if named differently than `name`. Installomator
|
||||
# will add the path to the folder/disk image with the binary, and it will be called like this:
|
||||
# $CLIInstaller $CLIArguments
|
||||
# For most installations `CLIInstaller` should contain the `installerTool` for the CLI call
|
||||
# (if it’s the same).
|
||||
# We can support a whole range of other software titles by implementing this.
|
||||
# See label adobecreativeclouddesktop
|
||||
#
|
||||
# - installerTool:
|
||||
# Introduced as part of `CLIInstaller`. If the installer in the DMG or ZIP is named
|
||||
# differently than the installed app, then this variable can be used to name the
|
||||
# installer that should be located after mounting/expanding the downloaded archive.
|
||||
# See label adobecreativeclouddesktop
|
||||
#
|
||||
### Logging
|
||||
# Logging behavior
|
||||
LOGGING="INFO"
|
||||
# options:
|
||||
# - DEBUG Everything is logged
|
||||
# - INFO (default) normal logging level
|
||||
# - WARN only warning
|
||||
# - ERROR only errors
|
||||
# - REQ ????
|
||||
|
||||
# MDM profile name
|
||||
MDMProfileName=""
|
||||
# options:
|
||||
# - MDM Profile Addigy has this name on the profile
|
||||
# - Mosyle Corporation MDM Mosyle uses this name on the profile
|
||||
# From the LOGO variable we can know if Addigy og Mosyle is used, so if that variable
|
||||
# is either of these, and this variable is empty, then we will auto detect this.
|
||||
|
||||
# Datadog logging used
|
||||
datadogAPI=""
|
||||
# Simply add your own API key for this in order to have logs sent to Datadog
|
||||
# See more here: https://www.datadoghq.com/product/log-management/
|
||||
|
||||
# Log Date format used when parsing logs for debugging, this is the default used by
|
||||
# install.log, override this in the case statements if you need something custom per
|
||||
# application (See adobeillustrator). Using stadard GNU Date formatting.
|
||||
LogDateFormat="%Y-%m-%d %H:%M:%S"
|
||||
|
||||
# Get the start time for parsing install.log if we fail.
|
||||
starttime=$(date "+$LogDateFormat")
|
||||
|
||||
# Check if we have rosetta installed
|
||||
if [[ $(/usr/bin/arch) == "arm64" ]]; then
|
||||
if ! arch -x86_64 /usr/bin/true >/dev/null 2>&1; then # pgrep oahd >/dev/null 2>&1
|
||||
rosetta2=no
|
||||
fi
|
||||
fi
|
||||
9
fragments/labels/1password7.sh
Normal file
9
fragments/labels/1password7.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
1password7)
|
||||
name="1Password 7"
|
||||
type="pkg"
|
||||
downloadURL="https://app-updates.agilebits.com/download/OPM7"
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[0-9a-zA-Z]*-([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="2BUA8C4S2C"
|
||||
blockingProcesses=( "1Password Extension Helper" "1Password 7" "1Password (Safari)" "1PasswordNativeMessageHost" "1PasswordSafariAppExtension" )
|
||||
#forcefulQuit=YES
|
||||
;;
|
||||
15
fragments/labels/1password8.sh
Normal file
15
fragments/labels/1password8.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
1password8)
|
||||
name="1Password 8"
|
||||
appName="1Password.app"
|
||||
type="zip"
|
||||
if [[ $(arch) == "arm64" ]]; then
|
||||
archiveName="1Password-latest-aarch64.zip"
|
||||
downloadURL="https://downloads.1password.com/mac/1Password-latest-aarch64.zip"
|
||||
elif [[ $(arch) == "i386" ]]; then
|
||||
archiveName="1Password-latest-x86_64.zip"
|
||||
downloadURL="https://downloads.1password.com/mac/1Password-latest-x86_64.zip"
|
||||
fi
|
||||
expectedTeamID="2BUA8C4S2C"
|
||||
blockingProcesses=( "1Password Extension Helper" "1Password 7" "1Password" "1Password (Safari)" "1PasswordNativeMessageHost" "1PasswordSafariAppExtension" )
|
||||
#forcefulQuit=YES
|
||||
;;
|
||||
9
fragments/labels/1passwordcli.sh
Normal file
9
fragments/labels/1passwordcli.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
1passwordcli)
|
||||
name="1Password CLI"
|
||||
type="pkg"
|
||||
#packageID="com.1password.op"
|
||||
downloadURL=$(curl -fs https://app-updates.agilebits.com/product_history/CLI | grep -m 1 -i op_apple_universal | cut -d'"' -f 2)
|
||||
appNewVersion=$(echo $downloadURL | sed -E 's/.*\/[a-zA-Z_]*([0-9.]*)\..*/\1/g')
|
||||
appCustomVersion(){ /usr/local/bin/op -v }
|
||||
expectedTeamID="2BUA8C4S2C"
|
||||
;;
|
||||
8
fragments/labels/4kvideodownloader.sh
Normal file
8
fragments/labels/4kvideodownloader.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
4kvideodownloader)
|
||||
name="4K Video Downloader"
|
||||
type="dmg"
|
||||
downloadURL="$(curl -fsL "https://www.4kdownload.com/products/product-videodownloader" | grep -E -o "https:\/\/dl\.4kdownload\.com\/app\/4kvideodownloader_.*?.dmg\?source=website" | head -1)"
|
||||
appNewVersion=$(echo "${downloadURL}" | sed -E 's/.*\/[0-9a-zA-Z]*_([0-9.]*)\.dmg.*/\1/g')
|
||||
versionKey="CFBundleVersion"
|
||||
expectedTeamID="GHQ37VJF83"
|
||||
;;
|
||||
9
fragments/labels/8x8.sh
Normal file
9
fragments/labels/8x8.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
8x8)
|
||||
# credit: #D-A-James from MacAdmins Slack and Isaac Ordonez, Mann consulting (@mannconsulting)
|
||||
name="8x8 Work"
|
||||
type="dmg"
|
||||
downloadURL=$(curl -fs -L https://support.8x8.com/cloud-phone-service/voice/work-desktop/download-8x8-work-for-desktop | grep -m 1 -o "https.*dmg" | sed 's/\"//' | awk '{print $1}')
|
||||
# As for appNewVersion, it needs to be checked for newer version than 7.2.4
|
||||
appNewVersion=$(curl -fs -L https://support.8x8.com/cloud-phone-service/voice/work-desktop/download-8x8-work-for-desktop | grep -m 1 -o "https.*dmg" | sed 's/\"//' | awk '{print $1}' | sed -E 's/.*-v([0-9\.]*)[-\.]*.*/\1/' )
|
||||
expectedTeamID="FC967L3QRG"
|
||||
;;
|
||||
7
fragments/labels/abetterfinderrename11.sh
Normal file
7
fragments/labels/abetterfinderrename11.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
abetterfinderrename11)
|
||||
name="A Better Finder Rename 11"
|
||||
type="dmg"
|
||||
downloadURL="https://www.publicspace.net/download/ABFRX11.dmg"
|
||||
appNewVersion=$(curl -fs "https://www.publicspace.net/app/signed_abfr11.xml" | xpath '(//rss/channel/item/enclosure/@sparkle:version)' 2>/dev/null | cut -d '"' -f 2)
|
||||
expectedTeamID="7Y9KW4ND8W"
|
||||
;;
|
||||
7
fragments/labels/abstract.sh
Normal file
7
fragments/labels/abstract.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
abstract)
|
||||
name="Abstract"
|
||||
type="zip"
|
||||
downloadURL="https://api.goabstract.com/releases/latest/download"
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="77MZLZE47D"
|
||||
;;
|
||||
9
fragments/labels/acroniscyberprotectconnect.sh
Normal file
9
fragments/labels/acroniscyberprotectconnect.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
acroniscyberprotectconnect|\
|
||||
remotix)
|
||||
name="Acronis Cyber Protect Connect"
|
||||
type="dmg"
|
||||
downloadURL="https://go.acronis.com/AcronisCyberProtectConnect_ForMac"
|
||||
versionKey="CFBundleVersion"
|
||||
appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i "^location" | sed -E 's/.*\/[a-zA-Z]*-[0-9.]*-([0-9.]*)\.dmg/\1/g')
|
||||
expectedTeamID="ZU2TV78AA6"
|
||||
;;
|
||||
11
fragments/labels/acroniscyberprotectconnectagent.sh
Normal file
11
fragments/labels/acroniscyberprotectconnectagent.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
acroniscyberprotectconnectagent|\
|
||||
remotixagent)
|
||||
name="Acronis Cyber Protect Connect Agent"
|
||||
type="pkg"
|
||||
#packageID="com.nulana.rxagentmac"
|
||||
downloadURL="https://go.acronis.com/AcronisCyberProtectConnect_AgentForMac"
|
||||
versionKey="CFBundleVersion"
|
||||
appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i "^location" | sed -E 's/.*\/[a-zA-Z]*-[0-9.]*-([0-9.]*)\.pkg/\1/g')
|
||||
expectedTeamID="H629V387SY"
|
||||
blockingProcesses=( NONE )
|
||||
;;
|
||||
8
fragments/labels/adobeacrobatprodc.sh
Normal file
8
fragments/labels/adobeacrobatprodc.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
adobeacrobatprodc)
|
||||
name="Adobe Acrobat Pro DC"
|
||||
type="pkgInDmg"
|
||||
downloadURL="https://trials.adobe.com/AdobeProducts/APRO/Acrobat_HelpX/osx10/Acrobat_DC_Web_WWMUI.dmg"
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
blockingProcesses=( "Acrobat Pro DC" )
|
||||
Company="Adobe"
|
||||
;;
|
||||
7
fragments/labels/adobebrackets.sh
Normal file
7
fragments/labels/adobebrackets.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
adobebrackets)
|
||||
name="Brackets"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit adobe brackets )
|
||||
appNewVersion=$(versionFromGit adobe brackets )
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
;;
|
||||
10
fragments/labels/adobeconnect.sh
Normal file
10
fragments/labels/adobeconnect.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
adobeconnect)
|
||||
# credit: Oh4sh0 https://github.com/Oh4sh0
|
||||
# Comment by Søren: I do not know this software.
|
||||
# Looks like it's an Adobe installer in an app, so it will probably not work
|
||||
name="AdobeConnectInstaller"
|
||||
type="dmg"
|
||||
downloadURL="http://www.adobe.com/go/ConnectSetupMac"
|
||||
appNewVersion=$(curl -fs https://helpx.adobe.com/adobe-connect/connect-downloads-updates.html | grep "Mac" | grep version | head -1 | sed -E 's/.*\(version ([0-9\.]*),.*/\1/g')
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
;;
|
||||
24
fragments/labels/adobecreativeclouddesktop.sh
Normal file
24
fragments/labels/adobecreativeclouddesktop.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
adobecreativeclouddesktop)
|
||||
name="Adobe Creative Cloud"
|
||||
appName="Install.app"
|
||||
type="dmg"
|
||||
if pgrep -q "Adobe Installer"; then
|
||||
printlog "Adobe Installer is running, not a good time to update." WARN
|
||||
printlog "################## End $APPLICATION \n\n" INFO
|
||||
exit 75
|
||||
fi
|
||||
if [[ "$(arch)" == "arm64" ]]; then
|
||||
downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o 'https.*macarm64.*dmg' | head -1 | cut -d '"' -f1)
|
||||
else
|
||||
downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o 'https.*osx10.*dmg' | head -1 | cut -d '"' -f1)
|
||||
fi
|
||||
#appNewVersion=$(curl -fs "https://helpx.adobe.com/creative-cloud/release-note/cc-release-notes.html" | grep "mandatory" | head -1 | grep -o "Version *.* released" | cut -d " " -f2)
|
||||
appNewVersion=$(echo $downloadURL | grep -o '[^x]*$' | cut -d '.' -f 1 | sed 's/_/\./g')
|
||||
targetDir="/Applications/Utilities/Adobe Creative Cloud/ACC/"
|
||||
installerTool="Install.app"
|
||||
CLIInstaller="Install.app/Contents/MacOS/Install"
|
||||
CLIArguments=(--mode=silent)
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
blockingProcesses=( "Creative Cloud" )
|
||||
Company="Adobe"
|
||||
;;
|
||||
27
fragments/labels/adobereaderdc-install.sh
Normal file
27
fragments/labels/adobereaderdc-install.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
adobereaderdc-install)
|
||||
name="Adobe Acrobat Reader DC"
|
||||
type="pkgInDmg"
|
||||
printlog "Changing IFS for Adobe Reader" INFO
|
||||
SAVEIFS=$IFS
|
||||
IFS=$'\n'
|
||||
versions=( $( curl -s https://www.adobe.com/devnet-docs/acrobatetk/tools/ReleaseNotesDC/index.html | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+"| head -n 30) )
|
||||
local version
|
||||
for version in $versions; do
|
||||
version="${version//.}"
|
||||
printlog "trying version: $version" INFO
|
||||
local httpstatus=$(curl -X HEAD -s "https://ardownload2.adobe.com/pub/adobe/reader/mac/AcrobatDC/${version}/AcroRdrDC_${version}_MUI.dmg" --write-out "%{http_code}")
|
||||
printlog "HTTP status for Adobe Reader full installer URL https://ardownload2.adobe.com/pub/adobe/reader/mac/AcrobatDC/${version}/AcroRdrDC_${version}_MUI.dmg is $httpstatus" DEBUG
|
||||
if [[ "${httpstatus}" == "200" ]]; then
|
||||
downloadURL="https://ardownload2.adobe.com/pub/adobe/reader/mac/AcrobatDC/${version}/AcroRdrDC_${version}_MUI.dmg"
|
||||
unset httpstatus
|
||||
break
|
||||
fi
|
||||
done
|
||||
unset version
|
||||
IFS=$SAVEIFS
|
||||
appNewVersion=$i
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
blockingProcesses=( "AdobeReader" )
|
||||
Company="Adobe"
|
||||
PatchName="AcrobatReader"
|
||||
;;
|
||||
44
fragments/labels/adobereaderdc-update.sh
Normal file
44
fragments/labels/adobereaderdc-update.sh
Normal file
@@ -0,0 +1,44 @@
|
||||
adobereaderdc-update)
|
||||
name="Adobe Acrobat Reader DC"
|
||||
type="pkgInDmg"
|
||||
if [[ -d "/Applications/Adobe Acrobat Reader DC.app" ]]; then
|
||||
printlog "Found /Applications/Adobe Acrobat Reader DC.app"
|
||||
mkdir -p "/Library/Application Support/Adobe/Acrobat/11.0"
|
||||
defaults write "/Library/Application Support/Adobe/Acrobat/11.0/com.adobe.Acrobat.InstallerOverrides.plist" ReaderAppPath "/Applications/Adobe Acrobat Reader DC.app"
|
||||
if ! defaults read "/Applications/Adobe Acrobat Reader DC.app/Contents/Resources/AcroLocale.plist" ; then
|
||||
printlog "Missing locale data, this will cause the updater to fail. Deleting Adobe Acrobat Reader DC.app and installing fresh." WARN
|
||||
rm -Rf "/Applications/Adobe Acrobat Reader DC.app"
|
||||
if [[ $1 == "/" ]]; then
|
||||
printlog "Running through Jamf: $0." INFO
|
||||
$0 $1 $2 $3 adobereaderdc-install ${5} ${6} ${7} ${8} ${9} ${10} ${11}
|
||||
else
|
||||
printlog "Installomator running locally: $0." INFO
|
||||
$0 adobereaderdc-install ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} ${10} ${11}
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
adobecurrent=$(curl -sL https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt | tr -d '.')
|
||||
if [[ "${adobecurrent}" != <-> ]]; then
|
||||
printlog "Got an invalid response for the Adobe Reader Current Version: ${adobecurrent}" ERROR
|
||||
printlog "################## End $APPLICATION \n\n" INFO
|
||||
exit 50
|
||||
fi
|
||||
downloadURL=$(echo https://ardownload2.adobe.com/pub/adobe/reader/mac/AcrobatDC/"$adobecurrent"/AcroRdrDCUpd"$adobecurrent"_MUI.dmg)
|
||||
reader_preinstall() {
|
||||
if pgrep -a "AdobeReader" >/dev/null 2>&1; then
|
||||
printlog "AdobeReader is still running, forcefully killing." WARN
|
||||
killall AdobeReader
|
||||
fi
|
||||
}
|
||||
preinstall="reader_preinstall"
|
||||
updateTool="/usr/local/bin/RemoteUpdateManager"
|
||||
updateToolArguments=( --productVersions=RDR )
|
||||
appNewVersion=$(curl -s https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt)
|
||||
updateToolLog="/Users/$currentUser/Library/Logs/RemoteUpdateManager.log"
|
||||
updateToolLogDateFormat="%m/%d/%y %H:%M:%S"
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
blockingProcesses=( "AdobeReader" )
|
||||
Company=Adobe
|
||||
PatchName=AcrobatReader
|
||||
PatchSkip="YES"
|
||||
;;
|
||||
12
fragments/labels/adobereaderdc.sh
Normal file
12
fragments/labels/adobereaderdc.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
adobereaderdc|\
|
||||
adobereaderdc-install)
|
||||
name="Adobe Acrobat Reader DC"
|
||||
type="pkgInDmg"
|
||||
packageID="com.adobe.acrobat.DC.reader.app.pkg.MUI"
|
||||
#downloadURL=$(curl --silent --fail -H "Sec-Fetch-Site: same-origin" -H "Accept-Encoding: gzip, deflate, br" -H "Accept-Language: en-US;q=0.9,en;q=0.8" -H "DNT: 1" -H "Sec-Fetch-Mode: cors" -H "X-Requested-With: XMLHttpRequest" -H "Referer: https://get.adobe.com/reader/enterprise/" -H "Accept: */*" "https://get.adobe.com/reader/webservices/json/standalone/?platform_type=Macintosh&platform_dist=OSX&platform_arch=x86-32&language=English&eventname=readerotherversions" | grep -Eo '"download_url":.*?[^\]",' | head -n 1 | cut -d \" -f 4)
|
||||
downloadURL=$(adobecurrent=`curl --fail --silent https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt | tr -d '.'` && echo https://ardownload2.adobe.com/pub/adobe/reader/mac/AcrobatDC/"$adobecurrent"/AcroRdrDC_"$adobecurrent"_MUI.dmg)
|
||||
appNewVersion=$(curl -s https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt)
|
||||
#appNewVersion=$(curl -s -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15)" https://get.adobe.com/reader/ | grep ">Version" | sed -E 's/.*Version 20([0-9.]*)<.*/\1/g') # credit: Søren Theilgaard (@theilgaard)
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
blockingProcesses=( "AdobeReader" )
|
||||
;;
|
||||
7
fragments/labels/aircall.sh
Normal file
7
fragments/labels/aircall.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
aircall)
|
||||
# credit: @kris-anderson
|
||||
name="Aircall"
|
||||
type="dmg"
|
||||
downloadURL="https://electron.aircall.io/download/osx"
|
||||
expectedTeamID="3ML357Q795"
|
||||
;;
|
||||
8
fragments/labels/airserver.sh
Normal file
8
fragments/labels/airserver.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
airserver)
|
||||
# credit: AP Orlebeke (@apizz)
|
||||
name="AirServer"
|
||||
type="dmg"
|
||||
downloadURL="https://www.airserver.com/download/mac/latest"
|
||||
appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i "location" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')
|
||||
expectedTeamID="6C755KS5W3"
|
||||
;;
|
||||
7
fragments/labels/airtame.sh
Normal file
7
fragments/labels/airtame.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
airtame)
|
||||
name="Airtame"
|
||||
type="dmg"
|
||||
downloadURL="$(curl -fs https://airtame.com/download/ | grep -i platform=mac | head -1 | grep -o -i -E "https.*" | cut -d '"' -f1)"
|
||||
appNewVersion="$(curl -fsIL "${downloadURL}" | grep -i ^location | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')"
|
||||
expectedTeamID="4TPSP88HN2"
|
||||
;;
|
||||
7
fragments/labels/aldente.sh
Normal file
7
fragments/labels/aldente.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
aldente)
|
||||
name="AlDente"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit davidwernhart AlDente)
|
||||
appNewVersion=$(versionFromGit davidwernhart AlDente)
|
||||
expectedTeamID="3WVC84GB99"
|
||||
;;
|
||||
7
fragments/labels/alephone.sh
Normal file
7
fragments/labels/alephone.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
alephone)
|
||||
name="Aleph One"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit Aleph-One-Marathon alephone)
|
||||
appNewVersion=$(versionFromGit Aleph-One-Marathon alephone)
|
||||
expectedTeamID="E8K89CXZE7"
|
||||
;;
|
||||
9
fragments/labels/alfred.sh
Normal file
9
fragments/labels/alfred.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
alfred)
|
||||
# credit: AP Orlebeke (@apizz)
|
||||
name="Alfred"
|
||||
type="dmg"
|
||||
downloadURL=$(curl -fs https://www.alfredapp.com | awk -F '"' "/dmg/ {print \$2}" | head -1)
|
||||
appNewVersion=$(echo "${downloadURL}" | sed -E 's/.*Alfred_([0-9.]*)_.*/\1/')
|
||||
appName="Alfred 4.app"
|
||||
expectedTeamID="XZZXE9SED4"
|
||||
;;
|
||||
7
fragments/labels/alttab.sh
Normal file
7
fragments/labels/alttab.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
alttab)
|
||||
# credit: Gabe Marchan (gabemarchan.com - @darklink87)
|
||||
name="AltTab"
|
||||
type="zip"
|
||||
downloadURL=$(downloadURLFromGit lwouis alt-tab-macos)
|
||||
expectedTeamID="QXD7GW8FHY"
|
||||
;;
|
||||
8
fragments/labels/amazonchime.sh
Normal file
8
fragments/labels/amazonchime.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
amazonchime)
|
||||
# credit: @dvsjr macadmins slack
|
||||
name="Amazon Chime"
|
||||
type="dmg"
|
||||
downloadURL="https://clients.chime.aws/mac/latest"
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[a-zA-Z.\-]*-([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="94KV3E626L"
|
||||
;;
|
||||
12
fragments/labels/amazoncorretto8jdk.sh
Normal file
12
fragments/labels/amazoncorretto8jdk.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
amazoncorretto8jdk)
|
||||
name="Amazon Corretto 8 JDK"
|
||||
type="pkg"
|
||||
if [[ $(arch) == "arm64" ]]; then
|
||||
downloadURL="https://corretto.aws/downloads/latest/amazon-corretto-8-aarch64-macos-jdk.pkg"
|
||||
appNewVersion=$(curl -s https://raw.githubusercontent.com/corretto/corretto-8/develop/CHANGELOG.md | grep "## Corretto version" | head -n 1 | awk '{ print $4; exit}')
|
||||
elif [[ $(arch) == "i386" ]]; then
|
||||
downloadURL="https://corretto.aws/downloads/latest/amazon-corretto-8-x64-macos-jdk.pkg"
|
||||
appNewVersion=$(curl -s https://raw.githubusercontent.com/corretto/corretto-8/develop/CHANGELOG.md | grep "## Corretto version" | head -n 1 | awk '{ print $4; exit}')
|
||||
fi
|
||||
expectedTeamID="94KV3E626L"
|
||||
;;
|
||||
8
fragments/labels/amazonworkspaces.sh
Normal file
8
fragments/labels/amazonworkspaces.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
amazonworkspaces)
|
||||
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
|
||||
name="Workspaces"
|
||||
type="pkg"
|
||||
downloadURL="https://d2td7dqidlhjx7.cloudfront.net/prod/global/osx/WorkSpaces.pkg"
|
||||
appNewVersion=$(curl -fs https://d2td7dqidlhjx7.cloudfront.net/prod/iad/osx/WorkSpacesAppCast_macOS_20171023.xml | grep -o "Version*.*<" | head -1 | cut -d " " -f2 | cut -d "<" -f1)
|
||||
expectedTeamID="94KV3E626L"
|
||||
;;
|
||||
6
fragments/labels/androidfiletransfer.sh
Normal file
6
fragments/labels/androidfiletransfer.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
androidfiletransfer)
|
||||
name="Android File Transfer"
|
||||
type="dmg"
|
||||
downloadURL="https://dl.google.com/dl/androidjumper/mtp/current/AndroidFileTransfer.dmg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
13
fragments/labels/androidstudio.sh
Normal file
13
fragments/labels/androidstudio.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
androidstudio)
|
||||
name="Android Studio"
|
||||
type="dmg"
|
||||
if [[ $(arch) == arm64 ]]; then
|
||||
downloadURL=$(curl -fsL "https://developer.android.com/studio#downloads" | grep -i arm.dmg | head -2 | grep -o -i -E "https.*" | cut -d '"' -f1)
|
||||
appNewVersion=$( echo "${downloadURL}" | head -1 | sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*$/\1/' )
|
||||
elif [[ $(arch) == i386 ]]; then
|
||||
downloadURL=$(curl -fsL "https://developer.android.com/studio#downloads" | grep -i mac.dmg | head -2 | grep -o -i -E "https.*" | cut -d '"' -f1)
|
||||
appNewVersion=$( echo "${downloadURL}" | head -1 | sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\).*$/\1/' )
|
||||
fi
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
blockingProcesses=( androidstudio )
|
||||
;;
|
||||
7
fragments/labels/anydesk.sh
Normal file
7
fragments/labels/anydesk.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
anydesk)
|
||||
name="AnyDesk"
|
||||
type="dmg"
|
||||
downloadURL="https://download.anydesk.com/anydesk.dmg"
|
||||
appNewVersion="$(curl -fs https://anydesk.com/da/downloads/mac-os | grep -i "d-block" | grep -E -o ">v[0-9.]* .*MB" | sed -E 's/.*v([0-9.]*) .*/\1/g')"
|
||||
expectedTeamID="KU6W3B6JMZ"
|
||||
;;
|
||||
7
fragments/labels/apparency.sh
Normal file
7
fragments/labels/apparency.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
apparency)
|
||||
name="Apparency"
|
||||
type="dmg"
|
||||
downloadURL="https://www.mothersruin.com/software/downloads/Apparency.dmg"
|
||||
appNewVersion=$(curl -fs https://mothersruin.com/software/Apparency/data/ApparencyVersionInfo.plist | grep -A1 CFBundleShortVersionString | tail -1 | sed -E 's/.*>([0-9.]*)<.*/\1/g')
|
||||
expectedTeamID="936EB786NH"
|
||||
;;
|
||||
7
fragments/labels/appcleaner.sh
Normal file
7
fragments/labels/appcleaner.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
appcleaner)
|
||||
name="AppCleaner"
|
||||
type="zip"
|
||||
downloadURL=$(curl -fs https://freemacsoft.net/appcleaner/Updates.xml | xpath '//rss/channel/item[last()]/enclosure/@url' 2>/dev/null | tr " " "\n" | sort | tail -1 | cut -d '"' -f 2)
|
||||
appNewVersion=$(curl -fsL "https://freemacsoft.net/appcleaner/Updates.xml" | xpath '//rss/channel/item[last()]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2)
|
||||
expectedTeamID="X85ZX835W9"
|
||||
;;
|
||||
7
fragments/labels/applenyfonts.sh
Normal file
7
fragments/labels/applenyfonts.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
applenyfonts)
|
||||
name="Apple New York Font Collection"
|
||||
type="pkgInDmg"
|
||||
downloadURL="https://devimages-cdn.apple.com/design/resources/download/NY.dmg"
|
||||
packageID="com.apple.pkg.NYFonts"
|
||||
expectedTeamID="Software Update"
|
||||
;;
|
||||
7
fragments/labels/applesfarabic.sh
Normal file
7
fragments/labels/applesfarabic.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
applesfarabic)
|
||||
name="San Francisco Arabic"
|
||||
type="pkgInDmg"
|
||||
downloadURL="https://devimages-cdn.apple.com/design/resources/download/SF-Arabic.dmg"
|
||||
packageID="com.apple.pkg.SFArabicFonts"
|
||||
expectedTeamID="Software Update"
|
||||
;;
|
||||
7
fragments/labels/applesfcompact.sh
Normal file
7
fragments/labels/applesfcompact.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
applesfcompact)
|
||||
name="San Francisco Compact"
|
||||
type="pkgInDmg"
|
||||
downloadURL="https://devimages-cdn.apple.com/design/resources/download/SF-Compact.dmg"
|
||||
packageID="com.apple.pkg.SanFranciscoCompact"
|
||||
expectedTeamID="Software Update"
|
||||
;;
|
||||
7
fragments/labels/applesfmono.sh
Normal file
7
fragments/labels/applesfmono.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
applesfmono)
|
||||
name="San Francisco Mono"
|
||||
type="pkgInDmg"
|
||||
downloadURL="https://devimages-cdn.apple.com/design/resources/download/SF-Mono.dmg"
|
||||
packageID="com.apple.pkg.SFMonoFonts"
|
||||
expectedTeamID="Software Update"
|
||||
;;
|
||||
7
fragments/labels/applesfpro.sh
Normal file
7
fragments/labels/applesfpro.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
applesfpro)
|
||||
name="San Francisco Pro"
|
||||
type="pkgInDmg"
|
||||
downloadURL="https://devimages-cdn.apple.com/design/resources/download/SF-Pro.dmg"
|
||||
packageID="com.apple.pkg.SanFranciscoPro"
|
||||
expectedTeamID="Software Update"
|
||||
;;
|
||||
8
fragments/labels/applesfsymbols.sh
Normal file
8
fragments/labels/applesfsymbols.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
applesfsymbols|\
|
||||
sfsymbols)
|
||||
name="SF Symbols"
|
||||
type="pkgInDmg"
|
||||
downloadURL=$( curl -fs "https://developer.apple.com/sf-symbols/" | grep -oe "https.*Symbols.*\.dmg" | head -1 )
|
||||
appNewVersion=$( echo "$downloadURL" | sed -E 's/.*SF-Symbols-([0-9.]*)\..*/\1/g')
|
||||
expectedTeamID="Software Update"
|
||||
;;
|
||||
8
fragments/labels/aquaskk.sh
Normal file
8
fragments/labels/aquaskk.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
aquaskk)
|
||||
# credit: Tadayuki Onishi (@kenchan0130)
|
||||
name="aquaskk"
|
||||
type="pkg"
|
||||
downloadURL=$(downloadURLFromGit codefirst aquaskk)
|
||||
appNewVersion=$(versionFromGit codefirst aquaskk)
|
||||
expectedTeamID="FPZK4WRGW7"
|
||||
;;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user