Compare commits

21 Commits

Author SHA1 Message Date
f1f67db3e4 Update Powershell/README.md 2026-04-23 11:49:01 +10:00
f0644294ee Update Powershell/README.md 2026-04-23 11:47:46 +10:00
c3cc6eb225 Add Powershell/Invoke-DiskSpaceReport.ps1
# Basic — drops HTML on Desktop
.\Invoke-DiskSpaceReport.ps1

# With client name in the header
.\Invoke-DiskSpaceReport.ps1 -ClientName "Department of X"

# Custom output path
.\Invoke-DiskSpaceReport.ps1 -OutputPath "C:\Reports" -ClientName "QPS"
2026-04-23 11:39:22 +10:00
70a93d54b2 Update Powershell/README.md 2026-04-23 09:59:45 +10:00
daec2070d8 Add Powershell/Invoke-DiskCleanupScan.ps1 2026-04-23 09:54:29 +10:00
5f4f0a9808 fixed the excess parentheses and ensured each function block closes properly. 2025-06-27 02:49:17 +00:00
2b1d775158 Replaced the unsupported ternary logic with a proper $target variable 2025-06-27 02:43:07 +00:00
1833c48409 Renamed File 2025-06-27 02:40:11 +00:00
b2469e962e Update Powershell/README.md 2025-06-27 02:39:40 +00:00
cafd06592f Update Powershell/README.md 2025-06-27 02:33:33 +00:00
dcf5428010 Add Powershell/README.md 2025-06-27 02:31:55 +00:00
9779a35c98 Create New File 2025-06-27 02:29:57 +00:00
605b2efbdc Add Powershell/SoftwareInstallScript 2025-06-12 04:27:48 +00:00
9e32e58cc0 Add Powershell/trustedhosts.ps1 2025-05-30 00:49:07 +00:00
DistractADD
80a3c501be Create List Recent Installed Hotfixes In Windows.ps1 2024-10-03 15:27:32 +10:00
DistractADD
3c467462e8 Create NEW_Assign_Teams_AU_or_NZ_DDI.ps1 2024-02-02 09:01:27 +10:00
DistractADD
e326cd97c0 Added from Evernote export 2024-02-02 08:54:43 +10:00
DistractADD
cfddd4fad2 Added Files 2021-07-06 13:16:46 +10:00
DistractADD
f2475a3bdd Added Files 2021-07-06 13:13:13 +10:00
DistractADD
b42ccc43b6 renamed file and removed directory 2021-07-06 13:05:15 +10:00
DistractADD
294eeba581 Create mswordfix.ps1 2021-07-06 13:03:35 +10:00
669 changed files with 1286082 additions and 0 deletions

Binary file not shown.

View File

@@ -0,0 +1,50 @@
Abbreviation,Definition
AB,Air Base
AC,Aircraft
ACAS,Airborne Collision Avoidance System
ACC,Area Control Centre
AF,Air Field
AFM,Aircraft Flight Manual
AIP,Aeronautical Information Publication
AMAN,Arrival Manager
AOA,Angle of Attack
AOM,Airplane Operating Manual
AOR,Area of Responsibility
AFIS,Aerodrome Flight Information Service
AFM,Airplane Flight Manual
AGL,Above Ground Level
AIP,Aeronautical Information Publication
ANSP,Air Navigation Service Provider
ARTCC,Air Route Traffic Control Centre
ASB,Airspace Block
ATA,Actual Time of Arrival
ATC,Air Traffic Control
ATIS,Automatic Terminal Information Service
ATO,Air Traffic Organization
BAF,Belgian Air Force
CAAC,Civil Aviation Administration of China
CAAS,Civil Aviation Authorization of Singapore
CANSO,Civil Air Navigation Services Organization
CAS,Calibrated Airspeed
CAT,Category of Aircraft
CAVOK,Ceiling And Visibility OK
COG,Center of Gravity
CRDA,Converging Runway Display Aid
CTA,Controlled Time of Arrival
CTA,Controlled Area
CTOT,Calculated Take-Off Time
CTR,Control Zone or Controlled Traffic Region
ECAC,European Civil Aviation Conference
FIA,Flight Information Area
FIR,Flight Information Region
FL,Flight Level
IAS,Indicated Air Speed
LL,Lower Limit
LTA,Lower Traffic Area
MEA,Minimum En-route Altitude
OCTA,Outside Control Areas
TA,Terminal Airspace
TAS,Terminal Airspace System
TMA,Terminal Control Area
UTA,Upper Traffic Area
VTC,Visual Terminal Chart
1 Abbreviation Definition
2 AB Air Base
3 AC Aircraft
4 ACAS Airborne Collision Avoidance System
5 ACC Area Control Centre
6 AF Air Field
7 AFM Aircraft Flight Manual
8 AIP Aeronautical Information Publication
9 AMAN Arrival Manager
10 AOA Angle of Attack
11 AOM Airplane Operating Manual
12 AOR Area of Responsibility
13 AFIS Aerodrome Flight Information Service
14 AFM Airplane Flight Manual
15 AGL Above Ground Level
16 AIP Aeronautical Information Publication
17 ANSP Air Navigation Service Provider
18 ARTCC Air Route Traffic Control Centre
19 ASB Airspace Block
20 ATA Actual Time of Arrival
21 ATC Air Traffic Control
22 ATIS Automatic Terminal Information Service
23 ATO Air Traffic Organization
24 BAF Belgian Air Force
25 CAAC Civil Aviation Administration of China
26 CAAS Civil Aviation Authorization of Singapore
27 CANSO Civil Air Navigation Services Organization
28 CAS Calibrated Airspeed
29 CAT Category of Aircraft
30 CAVOK Ceiling And Visibility OK
31 COG Center of Gravity
32 CRDA Converging Runway Display Aid
33 CTA Controlled Time of Arrival
34 CTA Controlled Area
35 CTOT Calculated Take-Off Time
36 CTR Control Zone or Controlled Traffic Region
37 ECAC European Civil Aviation Conference
38 FIA Flight Information Area
39 FIR Flight Information Region
40 FL Flight Level
41 IAS Indicated Air Speed
42 LL Lower Limit
43 LTA Lower Traffic Area
44 MEA Minimum En-route Altitude
45 OCTA Outside Control Areas
46 TA Terminal Airspace
47 TAS Terminal Airspace System
48 TMA Terminal Control Area
49 UTA Upper Traffic Area
50 VTC Visual Terminal Chart

View File

@@ -0,0 +1,46 @@
Abbreviation,Definition
ACID,"Atomicity, Consistency, Isolation, Durability"
ACL,Access Control List
ADC,Analog-to-Digital Converter
ADF,Automatic Document Feeder
ADSL,Asymmetric Digital Subscriber Line
AFP,Apple Filing Protocol
AGP,Accelerated Graphics Port
AIFF,Audio Interchange File Format
ALU,Arithmetic Logic Unit
ANSI,American National Standards Institute
API,Application Programming Interface
APU,Accelerated Processing Unit
ARP,Address Resolution Protocol
ASCII,American Standard Code for Information Interchange
ASP,Application Service Provider
ATM,Asynchronous Transfer Mode
AVR,Audio/Video Receiver
Bash,Bourne-Again Shell
BASIC,Beginner's All-purpose Symbolic Instruction Code
BCC,Blind Carbon Copy
BIOS,Basic Input/Output System
BLE,Bluetooth Low Energy
Blob,Binary Large Object
BMP,Bitmap
BSOD,Blue Screen of Death
CAD,Computer-Aided Design
CAN,Campus Area Network
CD,Compact Disc
CPU,Central Processing Unit
CSV,Comma Separated Values (file format)
DDL,Data Definition Language
IDE,Integrated Development Environment
GPU,Graphics Processing Unit
GUI,Graphical User Interface
IP,Internet Protocol
ISP,Internet Service Provider
IT,Information Technology
LAN,Local Area Network
LCD,Liquid Crystal Display
NIC,Network Interface Card
PC,Personal Computer
RAM,Random Access Memory
URL,Uniform Resource Locator
VPN,Virtual Private Network
WAN,Wide Area Network
1 Abbreviation Definition
2 ACID Atomicity, Consistency, Isolation, Durability
3 ACL Access Control List
4 ADC Analog-to-Digital Converter
5 ADF Automatic Document Feeder
6 ADSL Asymmetric Digital Subscriber Line
7 AFP Apple Filing Protocol
8 AGP Accelerated Graphics Port
9 AIFF Audio Interchange File Format
10 ALU Arithmetic Logic Unit
11 ANSI American National Standards Institute
12 API Application Programming Interface
13 APU Accelerated Processing Unit
14 ARP Address Resolution Protocol
15 ASCII American Standard Code for Information Interchange
16 ASP Application Service Provider
17 ATM Asynchronous Transfer Mode
18 AVR Audio/Video Receiver
19 Bash Bourne-Again Shell
20 BASIC Beginner's All-purpose Symbolic Instruction Code
21 BCC Blind Carbon Copy
22 BIOS Basic Input/Output System
23 BLE Bluetooth Low Energy
24 Blob Binary Large Object
25 BMP Bitmap
26 BSOD Blue Screen of Death
27 CAD Computer-Aided Design
28 CAN Campus Area Network
29 CD Compact Disc
30 CPU Central Processing Unit
31 CSV Comma Separated Values (file format)
32 DDL Data Definition Language
33 IDE Integrated Development Environment
34 GPU Graphics Processing Unit
35 GUI Graphical User Interface
36 IP Internet Protocol
37 ISP Internet Service Provider
38 IT Information Technology
39 LAN Local Area Network
40 LCD Liquid Crystal Display
41 NIC Network Interface Card
42 PC Personal Computer
43 RAM Random Access Memory
44 URL Uniform Resource Locator
45 VPN Virtual Private Network
46 WAN Wide Area Network

View File

@@ -0,0 +1,42 @@
Abbreviation,Definition
btl,Bottle
c,Cup
C,Cups
DF,Dairy free
doz,dozen
dp,drop
fl oz,Fluid ounce
fl ozs,Fluid ounces
g,Grams
gal,Gallons
gals,Gallons
GF,Gluten free
kg,Kilograms
L,Litres
l,Litres
lb,Pound
lbs,Pounds
lg,large
lge,large
md,medium
med,medium
mg,Milligrams
ml,Millilitres
NRV,Nutrient Reference Value
oz,Ounce
ozs,Ounces
pers,person(s)
pn,Pinch
pt,Pint
pts,Pints
qt,Quart
qts,Quarts
RI,Reference Intake
serv,serving
sm,small
srv,serving
Tbsp,Tablespoon
tsp,Teaspoon
VG,vegetarian
VN,Vegan
WF,Wheat free
1 Abbreviation Definition
2 btl Bottle
3 c Cup
4 C Cups
5 DF Dairy free
6 doz dozen
7 dp drop
8 fl oz Fluid ounce
9 fl ozs Fluid ounces
10 g Grams
11 gal Gallons
12 gals Gallons
13 GF Gluten free
14 kg Kilograms
15 L Litres
16 l Litres
17 lb Pound
18 lbs Pounds
19 lg large
20 lge large
21 md medium
22 med medium
23 mg Milligrams
24 ml Millilitres
25 NRV Nutrient Reference Value
26 oz Ounce
27 ozs Ounces
28 pers person(s)
29 pn Pinch
30 pt Pint
31 pts Pints
32 qt Quart
33 qts Quarts
34 RI Reference Intake
35 serv serving
36 sm small
37 srv serving
38 Tbsp Tablespoon
39 tsp Teaspoon
40 VG vegetarian
41 VN Vegan
42 WF Wheat free

View File

@@ -0,0 +1,14 @@
Abbreviation,Definition
PR,per the rectum
pr,per the rectum
PT,prothrombin time
PTT,partial thromboplastin time
pulv,powder
PV,per the vagina
q,every
q12h,every 12 hours
qd,daily
q1d,daily
q2h,every 2 hours
q3h,every 3 hours
q4h,every 4 hours
1 Abbreviation Definition
2 PR per the rectum
3 pr per the rectum
4 PT prothrombin time
5 PTT partial thromboplastin time
6 pulv powder
7 PV per the vagina
8 q every
9 q12h every 12 hours
10 qd daily
11 q1d daily
12 q2h every 2 hours
13 q3h every 3 hours
14 q4h every 4 hours

View File

@@ -0,0 +1,81 @@
Abbreviation,Definition
8va,Octave up
ad lib,Ad Libitum (“freely”)
afl,Alto flute
AS,Al Segno (“To the sign”)
bc,Basso Continuo (“continuous bass accompaniment”)
bcl,Bass clarinet
bfl,Bass flute
bpm,Beats per minute
bn,Bassoon
bob,Bass oboe
br,Brass instruments
bstcl,Basset clarinet
bsthn,Basset horn
bug,Bugle
cbcl,Contrabass clarinet
cbn,Contrabassoon
cf,Cantus Firmus (“main melody”)
cl,Clarinet
cresc,Crescendo (also noted as <)
crt,Cornet
D.C. al Coda,Da Capo al Coda (“from the beginning to the Coda sign”)
D.C. al Fine,Da Capo al Fine (“from the beginning to the end”)
D.S. al Fine,Dal Segno al Fine (“from the Segno mark to the end”)
decresc,Descrescendo (also noted as >)
dim,Diminuendo
eh,English horn
euph,Euphonium
f,Forte
fda,Flute damore (tenor flute)
ff,Fortissimo
fff,Fortississimo
fgh,Flugelhorn
fl,Flute
fp,Fortepiano
gliss,Glissando (“gliding, sliding”)
hn,Horn
m,Measure
mm,Measures
MM,Metronome tempo
mf,Mezzo-Forte
mp,Mezzo-Piano
mvt,Movement
ob,Oboe
oda,Oboe damore
orch,Orchestra
p,Piano
p,Page,
pan,Pan flute
pic,Piccolo
picc,Piccolo
pizz,Pizzicato (“plucking”)
pp,Pianissio
pp,Pages
ppp,Pianississimo
rall,Rallentando (“gradual slowing”)
rec,Recorder
rit,Ritardando (“slowing down”)
Rf,Rinforzando (“with sudden force”)
Rfz,Rinforzando (“with sudden force”)
rpm,Revolutions per minute
sax,Saxophone
sf,Sforzando, Sforzato (“sudden accent”)
sfz,Sforzando, Sforzato (“sudden accent”)
sfp,Sforzando followed by Piano
smorz,Smorzando (“dying away”)
sord,Sordino (“muted”)
sost. ped,Sostenuto pedal (“sustained pedal”)
spicc,Spiccato (“bounce bow on a stringed instrument”)
stacc,Staccato (“playing each note separately from the others”)
stpt,Slide trumpet
sul pont,Sul Ponticello (“playing with the bow near the bridge”)
tba,Tuba
tbn,Trombone
tpt,Trumpet
tr,Trill
trem,Tremolo (“trembling, wavering”)
tsx,Tenor saxophone
vib,Vibrato (“pulsing, vibrating”)
vol,Volume
ww,Woodwinds
1 Abbreviation Definition
2 8va Octave up
3 ad lib Ad Libitum (“freely”)
4 afl Alto flute
5 AS Al Segno (“To the sign”)
6 bc Basso Continuo (“continuous bass accompaniment”)
7 bcl Bass clarinet
8 bfl Bass flute
9 bpm Beats per minute
10 bn Bassoon
11 bob Bass oboe
12 br Brass instruments
13 bstcl Basset clarinet
14 bsthn Basset horn
15 bug Bugle
16 cbcl Contrabass clarinet
17 cbn Contrabassoon
18 cf Cantus Firmus (“main melody”)
19 cl Clarinet
20 cresc Crescendo (also noted as <)
21 crt Cornet
22 D.C. al Coda Da Capo al Coda (“from the beginning to the Coda sign”)
23 D.C. al Fine Da Capo al Fine (“from the beginning to the end”)
24 D.S. al Fine Dal Segno al Fine (“from the Segno mark to the end”)
25 decresc Descrescendo (also noted as >)
26 dim Diminuendo
27 eh English horn
28 euph Euphonium
29 f Forte
30 fda Flute d’amore (tenor flute)
31 ff Fortissimo
32 fff Fortississimo
33 fgh Flugelhorn
34 fl Flute
35 fp Fortepiano
36 gliss Glissando (“gliding sliding”)
37 hn Horn
38 m Measure
39 mm Measures
40 MM Metronome tempo
41 mf Mezzo-Forte
42 mp Mezzo-Piano
43 mvt Movement
44 ob Oboe
45 oda Oboe d’amore
46 orch Orchestra
47 p Piano
48 p Page
49 pan Pan flute
50 pic Piccolo
51 picc Piccolo
52 pizz Pizzicato (“plucking”)
53 pp Pianissio
54 pp Pages
55 ppp Pianississimo
56 rall Rallentando (“gradual slowing”)
57 rec Recorder
58 rit Ritardando (“slowing down”)
59 Rf Rinforzando (“with sudden force”)
60 Rfz Rinforzando (“with sudden force”)
61 rpm Revolutions per minute
62 sax Saxophone
63 sf Sforzando Sforzato (“sudden accent”)
64 sfz Sforzando Sforzato (“sudden accent”)
65 sfp Sforzando followed by Piano
66 smorz Smorzando (“dying away”)
67 sord Sordino (“muted”)
68 sost. ped Sostenuto pedal (“sustained pedal”)
69 spicc Spiccato (“bounce bow on a stringed instrument”)
70 stacc Staccato (“playing each note separately from the others”)
71 stpt Slide trumpet
72 sul pont Sul Ponticello (“playing with the bow near the bridge”)
73 tba Tuba
74 tbn Trombone
75 tpt Trumpet
76 tr Trill
77 trem Tremolo (“trembling wavering”)
78 tsx Tenor saxophone
79 vib Vibrato (“pulsing vibrating”)
80 vol Volume
81 ww Woodwinds

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
HEAD Handwashing
Wet your hands with clean, running water (warm or cold), turn off the tap, and apply soap.
Lather your hands by rubbing them together with the soap. Lather the backs of your hands, between your fingers, and under your nails.
Scrub your hands for at least 20 seconds.
Rinse your hands well under clean, running water.
Dry your hands using a clean towel or air dry them.

View File

@@ -0,0 +1,45 @@
Windows Terminal Cheat Sheet
============================
Application
-----------
Alt-F4 Close window
Ctrl-Shift-f Find
Ctrl-Shift-Space Open dropdown
Ctrl-, Open settings file
Alt-Enter Toggle full screen
F11
Tab Commands
------------
Ctrl-Shift-d Duplicate tab
Ctrl-Shift-t New tab
Ctrl-Shift-p New tab from profile p=1..9
Ctrl-Tab Switch to next tab
Ctrl-Shift-Tab Switch to previous tab
Ctrl-Alt-n Switch to tab n=0..9
Pane Commands
-------------
Alt-Shift-d Split pane optimally. Active profile.
Alt-Shift-- Split pane horizontally. Default profile.
Alt-Shift-+ Split pane vertically. Default profile.
Ctrl-Shift-w Close innermost pane, tab, or window
Clipboard Commands
------------------
Ctrl-c Copy
Ctrl-v Paste
Scrollback Commands
-------------------
Ctrl-Shift-up Scroll up
Ctrl-Shift-down Scroll down
Ctrl-Shift-pgup Scroll page up
Ctrl-Shift-pgdn Scroll page down
Visual Adjustment Commands
--------------------------
Ctrl-= Increase font size
Ctrl-- Decrease font size
Ctrl-0 Reset font size

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,185 @@
alpha2,English
aa,Afar
ab,Abkhazian
ae,Avestan
af,Afrikaans
ak,Akan
am,Amharic
an,Aragonese
ar,Arabic
as,Assamese
av,Avaric
ay,Aymara
az,Azerbaijani
ba,Bashkir
be,Belarusian
bg,Bulgarian
bh,Bihari languages
bi,Bislama
bm,Bambara
bn,Bengali
bo,Tibetan
br,Breton
bs,Bosnian
ca,Catalan; Valencian
ce,Chechen
ch,Chamorro
co,Corsican
cr,Cree
cs,Czech
cu,Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic
cv,Chuvash
cy,Welsh
da,Danish
de,German
dv,Divehi; Dhivehi; Maldivian
dz,Dzongkha
ee,Ewe
el,"Greek, Modern (1453-)"
en,English
eo,Esperanto
es,Spanish; Castilian
et,Estonian
eu,Basque
fa,Persian
ff,Fulah
fi,Finnish
fj,Fijian
fo,Faroese
fr,French
fy,Western Frisian
ga,Irish
gd,Gaelic; Scottish Gaelic
gl,Galician
gn,Guarani
gu,Gujarati
gv,Manx
ha,Hausa
he,Hebrew
hi,Hindi
ho,Hiri Motu
hr,Croatian
ht,Haitian; Haitian Creole
hu,Hungarian
hy,Armenian
hz,Herero
ia,Interlingua (International Auxiliary Language Association)
id,Indonesian
ie,Interlingue; Occidental
ig,Igbo
ii,Sichuan Yi; Nuosu
ik,Inupiaq
io,Ido
is,Icelandic
it,Italian
iu,Inuktitut
ja,Japanese
jv,Javanese
ka,Georgian
kg,Kongo
ki,Kikuyu; Gikuyu
kj,Kuanyama; Kwanyama
kk,Kazakh
kl,Kalaallisut; Greenlandic
km,Central Khmer
kn,Kannada
ko,Korean
kr,Kanuri
ks,Kashmiri
ku,Kurdish
kv,Komi
kw,Cornish
ky,Kirghiz; Kyrgyz
la,Latin
lb,Luxembourgish; Letzeburgesch
lg,Ganda
li,Limburgan; Limburger; Limburgish
ln,Lingala
lo,Lao
lt,Lithuanian
lu,Luba-Katanga
lv,Latvian
mg,Malagasy
mh,Marshallese
mi,Maori
mk,Macedonian
ml,Malayalam
mn,Mongolian
mr,Marathi
ms,Malay
mt,Maltese
my,Burmese
na,Nauru
nb,"Bokmål, Norwegian; Norwegian Bokmål"
nd,"Ndebele, North; North Ndebele"
ne,Nepali
ng,Ndonga
nl,Dutch; Flemish
nn,"Norwegian Nynorsk; Nynorsk, Norwegian"
no,Norwegian
nr,"Ndebele, South; South Ndebele"
nv,Navajo; Navaho
ny,Chichewa; Chewa; Nyanja
oc,Occitan (post 1500)
oj,Ojibwa
om,Oromo
or,Oriya
os,Ossetian; Ossetic
pa,Panjabi; Punjabi
pi,Pali
pl,Polish
ps,Pushto; Pashto
pt,Portuguese
qu,Quechua
rm,Romansh
rn,Rundi
ro,Romanian; Moldavian; Moldovan
ru,Russian
rw,Kinyarwanda
sa,Sanskrit
sc,Sardinian
sd,Sindhi
se,Northern Sami
sg,Sango
si,Sinhala; Sinhalese
sk,Slovak
sl,Slovenian
sm,Samoan
sn,Shona
so,Somali
sq,Albanian
sr,Serbian
ss,Swati
st,"Sotho, Southern"
su,Sundanese
sv,Swedish
sw,Swahili
ta,Tamil
te,Telugu
tg,Tajik
th,Thai
ti,Tigrinya
tk,Turkmen
tl,Tagalog
tn,Tswana
to,Tonga (Tonga Islands)
tr,Turkish
ts,Tsonga
tt,Tatar
tw,Twi
ty,Tahitian
ug,Uighur; Uyghur
uk,Ukrainian
ur,Urdu
uz,Uzbek
ve,Venda
vi,Vietnamese
vo,Volapük
wa,Walloon
wo,Wolof
xh,Xhosa
yi,Yiddish
yo,Yoruba
za,Zhuang; Chuang
zh,Chinese
zu,Zulu
1 alpha2 English
2 aa Afar
3 ab Abkhazian
4 ae Avestan
5 af Afrikaans
6 ak Akan
7 am Amharic
8 an Aragonese
9 ar Arabic
10 as Assamese
11 av Avaric
12 ay Aymara
13 az Azerbaijani
14 ba Bashkir
15 be Belarusian
16 bg Bulgarian
17 bh Bihari languages
18 bi Bislama
19 bm Bambara
20 bn Bengali
21 bo Tibetan
22 br Breton
23 bs Bosnian
24 ca Catalan; Valencian
25 ce Chechen
26 ch Chamorro
27 co Corsican
28 cr Cree
29 cs Czech
30 cu Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic
31 cv Chuvash
32 cy Welsh
33 da Danish
34 de German
35 dv Divehi; Dhivehi; Maldivian
36 dz Dzongkha
37 ee Ewe
38 el Greek, Modern (1453-)
39 en English
40 eo Esperanto
41 es Spanish; Castilian
42 et Estonian
43 eu Basque
44 fa Persian
45 ff Fulah
46 fi Finnish
47 fj Fijian
48 fo Faroese
49 fr French
50 fy Western Frisian
51 ga Irish
52 gd Gaelic; Scottish Gaelic
53 gl Galician
54 gn Guarani
55 gu Gujarati
56 gv Manx
57 ha Hausa
58 he Hebrew
59 hi Hindi
60 ho Hiri Motu
61 hr Croatian
62 ht Haitian; Haitian Creole
63 hu Hungarian
64 hy Armenian
65 hz Herero
66 ia Interlingua (International Auxiliary Language Association)
67 id Indonesian
68 ie Interlingue; Occidental
69 ig Igbo
70 ii Sichuan Yi; Nuosu
71 ik Inupiaq
72 io Ido
73 is Icelandic
74 it Italian
75 iu Inuktitut
76 ja Japanese
77 jv Javanese
78 ka Georgian
79 kg Kongo
80 ki Kikuyu; Gikuyu
81 kj Kuanyama; Kwanyama
82 kk Kazakh
83 kl Kalaallisut; Greenlandic
84 km Central Khmer
85 kn Kannada
86 ko Korean
87 kr Kanuri
88 ks Kashmiri
89 ku Kurdish
90 kv Komi
91 kw Cornish
92 ky Kirghiz; Kyrgyz
93 la Latin
94 lb Luxembourgish; Letzeburgesch
95 lg Ganda
96 li Limburgan; Limburger; Limburgish
97 ln Lingala
98 lo Lao
99 lt Lithuanian
100 lu Luba-Katanga
101 lv Latvian
102 mg Malagasy
103 mh Marshallese
104 mi Maori
105 mk Macedonian
106 ml Malayalam
107 mn Mongolian
108 mr Marathi
109 ms Malay
110 mt Maltese
111 my Burmese
112 na Nauru
113 nb Bokmål, Norwegian; Norwegian Bokmål
114 nd Ndebele, North; North Ndebele
115 ne Nepali
116 ng Ndonga
117 nl Dutch; Flemish
118 nn Norwegian Nynorsk; Nynorsk, Norwegian
119 no Norwegian
120 nr Ndebele, South; South Ndebele
121 nv Navajo; Navaho
122 ny Chichewa; Chewa; Nyanja
123 oc Occitan (post 1500)
124 oj Ojibwa
125 om Oromo
126 or Oriya
127 os Ossetian; Ossetic
128 pa Panjabi; Punjabi
129 pi Pali
130 pl Polish
131 ps Pushto; Pashto
132 pt Portuguese
133 qu Quechua
134 rm Romansh
135 rn Rundi
136 ro Romanian; Moldavian; Moldovan
137 ru Russian
138 rw Kinyarwanda
139 sa Sanskrit
140 sc Sardinian
141 sd Sindhi
142 se Northern Sami
143 sg Sango
144 si Sinhala; Sinhalese
145 sk Slovak
146 sl Slovenian
147 sm Samoan
148 sn Shona
149 so Somali
150 sq Albanian
151 sr Serbian
152 ss Swati
153 st Sotho, Southern
154 su Sundanese
155 sv Swedish
156 sw Swahili
157 ta Tamil
158 te Telugu
159 tg Tajik
160 th Thai
161 ti Tigrinya
162 tk Turkmen
163 tl Tagalog
164 tn Tswana
165 to Tonga (Tonga Islands)
166 tr Turkish
167 ts Tsonga
168 tt Tatar
169 tw Twi
170 ty Tahitian
171 ug Uighur; Uyghur
172 uk Ukrainian
173 ur Urdu
174 uz Uzbek
175 ve Venda
176 vi Vietnamese
177 vo Volapük
178 wa Walloon
179 wo Wolof
180 xh Xhosa
181 yi Yiddish
182 yo Yoruba
183 za Zhuang; Chuang
184 zh Chinese
185 zu Zulu

View File

@@ -0,0 +1,21 @@
Language, Popularity, Change
C, 12.54, -4.65
Python, 11.84, +3.48
Java, 11.54, -4.56
C++, 7.36, +1.41
C#, 4.33, -0.40
Visual Basic, 4.01, -0.68
JavaScript, 2.33, +0.06
PHP, 2.21, -0.05
Assembly language, 2.05, +1.09
SQL, 1.88, +0.15
Classic Visual Basic, 1.72, +1.07
Groovy, 1.29, +0.87
Ruby, 1.23, +0.25
R, 1.20, -0.99
Perl, 1.18, +0.36
Swift, 1.10, -0.35
Fortran, 1.07, +0.80
Delphi/Object Pascal, 1.06, +0.47
MATLAB, 1.05, +0.15
Go, 0.95, -0.06
1 Language Popularity Change
2 C 12.54 -4.65
3 Python 11.84 +3.48
4 Java 11.54 -4.56
5 C++ 7.36 +1.41
6 C# 4.33 -0.40
7 Visual Basic 4.01 -0.68
8 JavaScript 2.33 +0.06
9 PHP 2.21 -0.05
10 Assembly language 2.05 +1.09
11 SQL 1.88 +0.15
12 Classic Visual Basic 1.72 +1.07
13 Groovy 1.29 +0.87
14 Ruby 1.23 +0.25
15 R 1.20 -0.99
16 Perl 1.18 +0.36
17 Swift 1.10 -0.35
18 Fortran 1.07 +0.80
19 Delphi/Object Pascal 1.06 +0.47
20 MATLAB 1.05 +0.15
21 Go 0.95 -0.06

View File

@@ -0,0 +1,178 @@
Domain
3sat.de
access.ing.de
accounts.google.com
activity.windows.com
airbnb.com
airbnb.de
aka.ms
aldi-nord.de
aldi-sued.de
all-in.de
allgaeuer-zeitung.de
alternate.de
api.dropboxapi.com
api.met.no
api1.origin.com
arc.msn.com
arte.tv
assets.msn.com
amazon.com
amazon.de
amazon.fr
atcsim.de
banking.ing-diba.de
bergwelten.com
bild.de
bing.com
bing.de
bing.fr
blitzortung.org
bolt.dropbox.com
br.de
catalog.gamepass.com
changelogs.ubuntu.com
chip.de
client.dropbox.com
client.wns.windows.com
clients1.google.com
clients2.google.com
clients3.google.com
clients4.google.com
contacts.google.com
d.dropbox.com
dasoertliche.de
dealer.spotify.com
deepl.com
dell.com
discord.com
discordapp.com
dhl.de
download.windowsupdate.com
dropbox.com
earth.google.com
ebay.com
ebay.de
ebay.fr
ebay-kleinanzeigen.de
ebook3000.com
facebook.com
facebook.de
facebook.fr
fleschutz.de
flightradar24.com
focus.de
fonts.google.com
fonts.googleapis.com
fonts.gstatic.com
fosbos-kempten.de
github.com
github.map.fastly.net
gmail.com
golem.de
google.com
google.de
google.fr
googleapis.com
gstatic.com
heise.de
holidaycheck.de
hornbach.de
i.ytimg.com
IEEE.org
ibm.com
icons8.com
imap.googlemail.com
ing.de
install.robertsspaceindustries.com
ipfs.io
ipv6.msftconnecttest.com
launcher2.robertsspaceindustries.com
licensing.mp.microsoft.com
lidl.de
live.github.com
live.thunderbird.net
livepatch.canonical.com
login.live.com
login.hrworks.de
longfiles.com
mail.google.com
map.blitzortung.org
maps.google.com
maps.google.de
maps.google.fr
mebis.bayern.de
microsoft.com
mozilla.org
mtalk.google.com
music.google.com
mwittrien.github.io
netbeat.de
netflix.com
news.google.com
news.google.de
news.google.fr
news.url.google.com
notube.net
ogs.google.com
opera.com
photos.google.com
pixabay.com
play.google.com
plex.tv
posaunenchor-guenzach.de
presence.teams.microsoft.com
ptbtime1.ptb.de
ptbtime2.ptb.de
ptbtime3.ptb.de
rb-allgaeuerland.de
realschule-oberguenzburg.de
redbull.tv
redhat.com
reichelt.de
robertsspaceindustries.com
schneier.com
secure.download.dm.origin.com
semonkeys.net
settings.data.microsoft.com
settings-win.data.microsoft.com
sites.google.com
slashdot.com
speedtest.net
ssl.gstatic.com
stackoverflow.com
start.thunderbird.net
static.focus.de
static.nvidiagrid.net
storage.googleapis.com
substrate.office.com
t-online.de
t0.gstatic.com
tchibo.de
teams.microsoft.com
techstage.de
telemetry.dropbox.com
tile-service.weather.microsoft.com
time.windows.com
toggl.com
toom.de
track.toggl.com
translate.google.de
twitter.com
twitter.de
ubuntu.com
ufainc.com
update.googleapis.com
wetter.com
wetter.de
wired.com
ws-kempten.de
wttr.in
www.google.com
www.googleapis.com
www.gstatic.com
www.netflix.com
www.youtube.com
youtube.com
youtube.de
zdf.de
1 Domain
2 3sat.de
3 access.ing.de
4 accounts.google.com
5 activity.windows.com
6 airbnb.com
7 airbnb.de
8 aka.ms
9 aldi-nord.de
10 aldi-sued.de
11 all-in.de
12 allgaeuer-zeitung.de
13 alternate.de
14 api.dropboxapi.com
15 api.met.no
16 api1.origin.com
17 arc.msn.com
18 arte.tv
19 assets.msn.com
20 amazon.com
21 amazon.de
22 amazon.fr
23 atcsim.de
24 banking.ing-diba.de
25 bergwelten.com
26 bild.de
27 bing.com
28 bing.de
29 bing.fr
30 blitzortung.org
31 bolt.dropbox.com
32 br.de
33 catalog.gamepass.com
34 changelogs.ubuntu.com
35 chip.de
36 client.dropbox.com
37 client.wns.windows.com
38 clients1.google.com
39 clients2.google.com
40 clients3.google.com
41 clients4.google.com
42 contacts.google.com
43 d.dropbox.com
44 dasoertliche.de
45 dealer.spotify.com
46 deepl.com
47 dell.com
48 discord.com
49 discordapp.com
50 dhl.de
51 download.windowsupdate.com
52 dropbox.com
53 earth.google.com
54 ebay.com
55 ebay.de
56 ebay.fr
57 ebay-kleinanzeigen.de
58 ebook3000.com
59 facebook.com
60 facebook.de
61 facebook.fr
62 fleschutz.de
63 flightradar24.com
64 focus.de
65 fonts.google.com
66 fonts.googleapis.com
67 fonts.gstatic.com
68 fosbos-kempten.de
69 github.com
70 github.map.fastly.net
71 gmail.com
72 golem.de
73 google.com
74 google.de
75 google.fr
76 googleapis.com
77 gstatic.com
78 heise.de
79 holidaycheck.de
80 hornbach.de
81 i.ytimg.com
82 IEEE.org
83 ibm.com
84 icons8.com
85 imap.googlemail.com
86 ing.de
87 install.robertsspaceindustries.com
88 ipfs.io
89 ipv6.msftconnecttest.com
90 launcher2.robertsspaceindustries.com
91 licensing.mp.microsoft.com
92 lidl.de
93 live.github.com
94 live.thunderbird.net
95 livepatch.canonical.com
96 login.live.com
97 login.hrworks.de
98 longfiles.com
99 mail.google.com
100 map.blitzortung.org
101 maps.google.com
102 maps.google.de
103 maps.google.fr
104 mebis.bayern.de
105 microsoft.com
106 mozilla.org
107 mtalk.google.com
108 music.google.com
109 mwittrien.github.io
110 netbeat.de
111 netflix.com
112 news.google.com
113 news.google.de
114 news.google.fr
115 news.url.google.com
116 notube.net
117 ogs.google.com
118 opera.com
119 photos.google.com
120 pixabay.com
121 play.google.com
122 plex.tv
123 posaunenchor-guenzach.de
124 presence.teams.microsoft.com
125 ptbtime1.ptb.de
126 ptbtime2.ptb.de
127 ptbtime3.ptb.de
128 rb-allgaeuerland.de
129 realschule-oberguenzburg.de
130 redbull.tv
131 redhat.com
132 reichelt.de
133 robertsspaceindustries.com
134 schneier.com
135 secure.download.dm.origin.com
136 semonkeys.net
137 settings.data.microsoft.com
138 settings-win.data.microsoft.com
139 sites.google.com
140 slashdot.com
141 speedtest.net
142 ssl.gstatic.com
143 stackoverflow.com
144 start.thunderbird.net
145 static.focus.de
146 static.nvidiagrid.net
147 storage.googleapis.com
148 substrate.office.com
149 t-online.de
150 t0.gstatic.com
151 tchibo.de
152 teams.microsoft.com
153 techstage.de
154 telemetry.dropbox.com
155 tile-service.weather.microsoft.com
156 time.windows.com
157 toggl.com
158 toom.de
159 track.toggl.com
160 translate.google.de
161 twitter.com
162 twitter.de
163 ubuntu.com
164 ufainc.com
165 update.googleapis.com
166 wetter.com
167 wetter.de
168 wired.com
169 ws-kempten.de
170 wttr.in
171 www.google.com
172 www.googleapis.com
173 www.gstatic.com
174 www.netflix.com
175 www.youtube.com
176 youtube.com
177 youtube.de
178 zdf.de

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
Category,FolderName,Branch,Shallow,URL
Dev, base256unicode,master, no, "https://github.com/fleschutz/base256unicode"
Dev, bazel, master, yes, "https://github.com/bazelbuild/bazel"
Dev, cmake, master, yes, "https://github.com/Kitware/CMake"
Fun, cmatrix, master, yes, "https://github.com/abishekvashok/cmatrix"
Tool, cmark, master, yes, "https://github.com/commonmark/cmark"
Dev, CWTS, master, no, "https://github.com/fleschutz/CWTS"
Tool, elasticsearch, master, yes, "https://github.com/elastic/elasticsearch"
Tool, go-ipfs, master, yes, "https://github.com/ipfs/go-ipfs"
Tool, grafana, main, yes, "https://github.com/grafana/grafana"
Dev, llvm, master, yes, "https://github.com/llvm/llvm-project"
Math, LSS, master, yes, "https://github.com/fleschutz/LSS"
Dev, ninja, master, yes, "git://github.com/ninja-build/ninja.git"
Libs, opencv, master, yes, "https://github.com/opencv/opencv"
Tool, OSMA, master, no, "https://github.com/fleschutz/OSMA"
Shell, PowerShell, master, no, "https://github.com/fleschutz/PowerShell"
Shell, pwsh, master, yes, "https://github.com/PowerShell/PowerShell"
Dev, protobuf, master, yes, "https://github.com/protocolbuffers/protobuf"
Dev, rust, master, yes, "https://github.com/rust-lang/rust"
Tool, smartmontools, master, yes, "https://github.com/smartmontools/smartmontools"
Tool, tensorflow, master, yes, "https://github.com/tensorflow/tensorflow"
Tool, terminal, main, yes, "https://github.com/microsoft/terminal"
Dev, tinycc, mob, yes, "https://github.com/TinyCC/tinycc"
Tool, voice2json, master, yes, "https://github.com/synesthesiam/voice2json"
Tool, zfs, master, yes, "https://github.com/openzfs/zfs"
1 Category,FolderName,Branch,Shallow,URL
2 Dev, base256unicode,master, no, https://github.com/fleschutz/base256unicode
3 Dev, bazel, master, yes, https://github.com/bazelbuild/bazel
4 Dev, cmake, master, yes, https://github.com/Kitware/CMake
5 Fun, cmatrix, master, yes, https://github.com/abishekvashok/cmatrix
6 Tool, cmark, master, yes, https://github.com/commonmark/cmark
7 Dev, CWTS, master, no, https://github.com/fleschutz/CWTS
8 Tool, elasticsearch, master, yes, https://github.com/elastic/elasticsearch
9 Tool, go-ipfs, master, yes, https://github.com/ipfs/go-ipfs
10 Tool, grafana, main, yes, https://github.com/grafana/grafana
11 Dev, llvm, master, yes, https://github.com/llvm/llvm-project
12 Math, LSS, master, yes, https://github.com/fleschutz/LSS
13 Dev, ninja, master, yes, git://github.com/ninja-build/ninja.git
14 Libs, opencv, master, yes, https://github.com/opencv/opencv
15 Tool, OSMA, master, no, https://github.com/fleschutz/OSMA
16 Shell, PowerShell, master, no, https://github.com/fleschutz/PowerShell
17 Shell, pwsh, master, yes, https://github.com/PowerShell/PowerShell
18 Dev, protobuf, master, yes, https://github.com/protocolbuffers/protobuf
19 Dev, rust, master, yes, https://github.com/rust-lang/rust
20 Tool, smartmontools, master, yes, https://github.com/smartmontools/smartmontools
21 Tool, tensorflow, master, yes, https://github.com/tensorflow/tensorflow
22 Tool, terminal, main, yes, https://github.com/microsoft/terminal
23 Dev, tinycc, mob, yes, https://github.com/TinyCC/tinycc
24 Tool, voice2json, master, yes, https://github.com/synesthesiam/voice2json
25 Tool, zfs, master, yes, https://github.com/openzfs/zfs

View File

@@ -0,0 +1,65 @@
"StatusCode","Type","ShortDescription","LongDescription"
"100","Informational","Continue ","The initial part of a request has been received and has not yet been rejected by the server. The server intends to send a final response after the request has been fully received and acted upon."
"101","Informational","Switching Protocols ","The server understands and is willing to comply with the client's request, via the Upgrade header field1, for a change in the application protocol being used on this connection."
"102","Informational","Processing ","An interim response used to inform the client that the server has accepted the complete request, but has not yet completed it."
"200","Success","OK ","The request has succeeded."
"201","Success","Created ","The request has been fulfilled and has resulted in one or more new resources being created."
"202","Success","Accepted ","The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place."
"203","Success","Non-authoritative Information ","The request was successful but the enclosed payload has been modified from that of the origin server's 200 OK response by a transforming proxy1."
"204","Success","No Content ","The server has successfully fulfilled the request and that there is no additional content to send in the response payload body."
"205","Success","Reset Content ","The server has fulfilled the request and desires that the user agent reset the ""document view"", which caused the request to be sent, to its original state as received from the origin server."
"206","Success","Partial Content ","The server is successfully fulfilling a range request for the target resource by transferring one or more parts of the selected representation that correspond to the satisfiable ranges found in the request's Range header field1."
"207","Success","Multi-Status ","A Multi-Status response conveys information about multiple resources in situations where multiple status codes might be appropriate."
"208","Success","Already Reported ","Used inside a DAV: propstat response element to avoid enumerating the internal members of multiple bindings to the same collection repeatedly."
"226","Success","IM Used ","The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance."
"300","Redirection","Multiple Choices ","The target resource has more than one representation, each with its own more specific identifier, and information about the alternatives is being provided so that the user (or user agent) can select a preferred representation by redirecting its request to one or more of those identifiers."
"301","Redirection","Moved Permanently ","The target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs."
"302","Redirection","Found ","The target resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client ought to continue to use the effective request URI for future requests."
"303","Redirection","See Other ","The server is redirecting the user agent to a different resource, as indicated by a URI in the Location header field, which is intended to provide an indirect response to the original request."
"304","Redirection","Not Modified ","A conditional GET or HEAD request has been received and would have resulted in a 200 OK response if it were not for the fact that the condition evaluated to false."
"305","Redirection","Use Proxy ","Defined in a previous version of this specification and is now deprecated, due to security concerns regarding in-band configuration of a proxy."
"307","Redirection","Temporary Redirect ","The target resource resides temporarily under a different URI and the user agent MUST NOT change the request method if it performs an automatic redirection to that URI."
"308","Redirection","Permanent Redirect ","The target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs."
"400","Client Error","Bad Request ","The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)."
"401","Client Error","Unauthorized ","The request has not been applied because it lacks valid authentication credentials for the target resource."
"402","Client Error","Payment Required ","Reserved for future use."
"403","Client Error","Forbidden ","The server understood the request but refuses to authorize it."
"404","Client Error","Not Found ","The origin server did not find a current representation for the target resource or is not willing to disclose that one exists."
"405","Client Error","Method Not Allowed ","The method received in the request-line is known by the origin server but not supported by the target resource."
"406","Client Error","Not Acceptable ","The target resource does not have a current representation that would be acceptable to the user agent, according to the proactive negotiation header fields received in the request1, and the server is unwilling to supply a default representation."
"407","Client Error","Proxy Authentication Required ","Similar to 401 Unauthorized, but it indicates that the client needs to authenticate itself in order to use a proxy."
"408","Client Error","Request Timeout ","The server did not receive a complete request message within the time that it was prepared to wait."
"409","Client Error","Conflict ","The request could not be completed due to a conflict with the current state of the target resource. This code is used in situations where the user might be able to resolve the conflict and resubmit the request."
"410","Client Error","Gone ","The target resource is no longer available at the origin server and that this condition is likely to be permanent."
"411","Client Error","Length Required ","The server refuses to accept the request without a defined Content-Length1."
"412","Client Error","Precondition Failed ","One or more conditions given in the request header fields evaluated to false when tested on the server."
"413","Client Error","Payload Too Large ","The server is refusing to process a request because the request payload is larger than the server is willing or able to process."
"414","Client Error","Request-URI Too Long ","The server is refusing to service the request because the request-target1 is longer than the server is willing to interpret."
"415","Client Error","Unsupported Media Type ","The origin server is refusing to service the request because the payload is in a format not supported by this method on the target resource."
"416","Client Error","Requested Range Not Satisfiable ","None of the ranges in the request's Range header field1 overlap the current extent of the selected resource or that the set of ranges requested has been rejected due to invalid ranges or an excessive request of small or overlapping ranges."
"417","Client Error","Expectation Failed ","The expectation given in the request's Expect header field1 could not be met by at least one of the inbound servers."
"418","Client Error","I'm a teapot ","Any attempt to brew coffee with a teapot should result in the error code ""418 I'm a teapot"". The resulting entity body MAY be short and stout."
"421","Client Error","Misdirected Request ","The request was directed at a server that is not able to produce a response. This can be sent by a server that is not configured to produce responses for the combination of scheme and authority that are included in the request URI."
"422","Client Error","Unprocessable Entity ","The server understands the content type of the request entity (hence a 415 Unsupported Media Type status code is inappropriate), and the syntax of the request entity is correct (thus a 400 Bad Request status code is inappropriate) but was unable to process the contained instructions."
"423","Client Error","Locked ","The source or destination resource of a method is locked."
"424","Client Error","Failed Dependency ","The method could not be performed on the resource because the requested action depended on another action and that action failed."
"426","Client Error","Upgrade Required ","The server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol."
"428","Client Error","Precondition Required ","The origin server requires the request to be conditional."
"429","Client Error","Too Many Requests ","The user has sent too many requests in a given amount of time (""rate limiting"")."
"431","Client Error","Request Header Fields Too Large ","The server is unwilling to process the request because its header fields are too large. The request MAY be resubmitted after reducing the size of the request header fields."
"444","Client Error","Connection Closed Without Response ","A non-standard status code used to instruct nginx to close the connection without sending a response to the client, most commonly used to deny malicious or malformed requests."
"451","Client Error","Unavailable For Legal Reasons ","The server is denying access to the resource as a consequence of a legal demand."
"499","Client Error","Client Closed Request ","A non-standard status code introduced by nginx for the case when a client closes the connection while nginx is processing the request."
"500","Server Error","Internal Server Error ","The server encountered an unexpected condition that prevented it from fulfilling the request."
"501","Server Error","Not Implemented ","The server does not support the functionality required to fulfill the request."
"502","Server Error","Bad Gateway ","The server, while acting as a gateway or proxy, received an invalid response from an inbound server it accessed while attempting to fulfill the request."
"503","Server Error","Service Unavailable ","The server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be alleviated after some delay."
"504","Server Error","Gateway Timeout ","The server, while acting as a gateway or proxy, did not receive a timely response from an upstream server it needed to access in order to complete the request."
"505","Server Error","HTTP Version Not Supported ","The server does not support, or refuses to support, the major version of HTTP that was used in the request message."
"506","Server Error","Variant Also Negotiates ","The server has an internal configuration error: the chosen variant resource is configured to engage in transparent content negotiation itself, and is therefore not a proper end point in the negotiation process."
"507","Server Error","Insufficient Storage ","The method could not be performed on the resource because the server is unable to store the representation needed to successfully complete the request."
"508","Server Error","Loop Detected ","The server terminated an operation because it encountered an infinite loop while processing a request with ""Depth: infinity"". This status indicates that the entire operation failed."
"510","Server Error","Not Extended ","The policy for accessing the resource has not been met in the request. The server should send back all the information necessary for the client to issue an extended request."
"511","Server Error","Network Authentication Required ","The client needs to authenticate to gain network access."
"599","Server Error","Network Connect Timeout Error ","This status code is not specified in any RFCs, but is used by some HTTP proxies to signal a network connect timeout behind the proxy to a client in front of the proxy."
1 StatusCode Type ShortDescription LongDescription
2 100 Informational Continue The initial part of a request has been received and has not yet been rejected by the server. The server intends to send a final response after the request has been fully received and acted upon.
3 101 Informational Switching Protocols The server understands and is willing to comply with the client's request, via the Upgrade header field1, for a change in the application protocol being used on this connection.
4 102 Informational Processing An interim response used to inform the client that the server has accepted the complete request, but has not yet completed it.
5 200 Success OK The request has succeeded.
6 201 Success Created The request has been fulfilled and has resulted in one or more new resources being created.
7 202 Success Accepted The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place.
8 203 Success Non-authoritative Information The request was successful but the enclosed payload has been modified from that of the origin server's 200 OK response by a transforming proxy1.
9 204 Success No Content The server has successfully fulfilled the request and that there is no additional content to send in the response payload body.
10 205 Success Reset Content The server has fulfilled the request and desires that the user agent reset the "document view", which caused the request to be sent, to its original state as received from the origin server.
11 206 Success Partial Content The server is successfully fulfilling a range request for the target resource by transferring one or more parts of the selected representation that correspond to the satisfiable ranges found in the request's Range header field1.
12 207 Success Multi-Status A Multi-Status response conveys information about multiple resources in situations where multiple status codes might be appropriate.
13 208 Success Already Reported Used inside a DAV: propstat response element to avoid enumerating the internal members of multiple bindings to the same collection repeatedly.
14 226 Success IM Used The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
15 300 Redirection Multiple Choices The target resource has more than one representation, each with its own more specific identifier, and information about the alternatives is being provided so that the user (or user agent) can select a preferred representation by redirecting its request to one or more of those identifiers.
16 301 Redirection Moved Permanently The target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs.
17 302 Redirection Found The target resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client ought to continue to use the effective request URI for future requests.
18 303 Redirection See Other The server is redirecting the user agent to a different resource, as indicated by a URI in the Location header field, which is intended to provide an indirect response to the original request.
19 304 Redirection Not Modified A conditional GET or HEAD request has been received and would have resulted in a 200 OK response if it were not for the fact that the condition evaluated to false.
20 305 Redirection Use Proxy Defined in a previous version of this specification and is now deprecated, due to security concerns regarding in-band configuration of a proxy.
21 307 Redirection Temporary Redirect The target resource resides temporarily under a different URI and the user agent MUST NOT change the request method if it performs an automatic redirection to that URI.
22 308 Redirection Permanent Redirect The target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs.
23 400 Client Error Bad Request The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
24 401 Client Error Unauthorized The request has not been applied because it lacks valid authentication credentials for the target resource.
25 402 Client Error Payment Required Reserved for future use.
26 403 Client Error Forbidden The server understood the request but refuses to authorize it.
27 404 Client Error Not Found The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
28 405 Client Error Method Not Allowed The method received in the request-line is known by the origin server but not supported by the target resource.
29 406 Client Error Not Acceptable The target resource does not have a current representation that would be acceptable to the user agent, according to the proactive negotiation header fields received in the request1, and the server is unwilling to supply a default representation.
30 407 Client Error Proxy Authentication Required Similar to 401 Unauthorized, but it indicates that the client needs to authenticate itself in order to use a proxy.
31 408 Client Error Request Timeout The server did not receive a complete request message within the time that it was prepared to wait.
32 409 Client Error Conflict The request could not be completed due to a conflict with the current state of the target resource. This code is used in situations where the user might be able to resolve the conflict and resubmit the request.
33 410 Client Error Gone The target resource is no longer available at the origin server and that this condition is likely to be permanent.
34 411 Client Error Length Required The server refuses to accept the request without a defined Content-Length1.
35 412 Client Error Precondition Failed One or more conditions given in the request header fields evaluated to false when tested on the server.
36 413 Client Error Payload Too Large The server is refusing to process a request because the request payload is larger than the server is willing or able to process.
37 414 Client Error Request-URI Too Long The server is refusing to service the request because the request-target1 is longer than the server is willing to interpret.
38 415 Client Error Unsupported Media Type The origin server is refusing to service the request because the payload is in a format not supported by this method on the target resource.
39 416 Client Error Requested Range Not Satisfiable None of the ranges in the request's Range header field1 overlap the current extent of the selected resource or that the set of ranges requested has been rejected due to invalid ranges or an excessive request of small or overlapping ranges.
40 417 Client Error Expectation Failed The expectation given in the request's Expect header field1 could not be met by at least one of the inbound servers.
41 418 Client Error I'm a teapot Any attempt to brew coffee with a teapot should result in the error code "418 I'm a teapot". The resulting entity body MAY be short and stout.
42 421 Client Error Misdirected Request The request was directed at a server that is not able to produce a response. This can be sent by a server that is not configured to produce responses for the combination of scheme and authority that are included in the request URI.
43 422 Client Error Unprocessable Entity The server understands the content type of the request entity (hence a 415 Unsupported Media Type status code is inappropriate), and the syntax of the request entity is correct (thus a 400 Bad Request status code is inappropriate) but was unable to process the contained instructions.
44 423 Client Error Locked The source or destination resource of a method is locked.
45 424 Client Error Failed Dependency The method could not be performed on the resource because the requested action depended on another action and that action failed.
46 426 Client Error Upgrade Required The server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol.
47 428 Client Error Precondition Required The origin server requires the request to be conditional.
48 429 Client Error Too Many Requests The user has sent too many requests in a given amount of time ("rate limiting").
49 431 Client Error Request Header Fields Too Large The server is unwilling to process the request because its header fields are too large. The request MAY be resubmitted after reducing the size of the request header fields.
50 444 Client Error Connection Closed Without Response A non-standard status code used to instruct nginx to close the connection without sending a response to the client, most commonly used to deny malicious or malformed requests.
51 451 Client Error Unavailable For Legal Reasons The server is denying access to the resource as a consequence of a legal demand.
52 499 Client Error Client Closed Request A non-standard status code introduced by nginx for the case when a client closes the connection while nginx is processing the request.
53 500 Server Error Internal Server Error The server encountered an unexpected condition that prevented it from fulfilling the request.
54 501 Server Error Not Implemented The server does not support the functionality required to fulfill the request.
55 502 Server Error Bad Gateway The server, while acting as a gateway or proxy, received an invalid response from an inbound server it accessed while attempting to fulfill the request.
56 503 Server Error Service Unavailable The server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be alleviated after some delay.
57 504 Server Error Gateway Timeout The server, while acting as a gateway or proxy, did not receive a timely response from an upstream server it needed to access in order to complete the request.
58 505 Server Error HTTP Version Not Supported The server does not support, or refuses to support, the major version of HTTP that was used in the request message.
59 506 Server Error Variant Also Negotiates The server has an internal configuration error: the chosen variant resource is configured to engage in transparent content negotiation itself, and is therefore not a proper end point in the negotiation process.
60 507 Server Error Insufficient Storage The method could not be performed on the resource because the server is unable to store the representation needed to successfully complete the request.
61 508 Server Error Loop Detected The server terminated an operation because it encountered an infinite loop while processing a request with "Depth: infinity". This status indicates that the entire operation failed.
62 510 Server Error Not Extended The policy for accessing the resource has not been met in the request. The server should send back all the information necessary for the client to issue an extended request.
63 511 Server Error Network Authentication Required The client needs to authenticate to gain network access.
64 599 Server Error Network Connect Timeout Error This status code is not specified in any RFCs, but is used by some HTTP proxies to signal a network connect timeout behind the proxy to a client in front of the proxy.

69
Powershell/Data/jokes.csv Normal file
View File

@@ -0,0 +1,69 @@
Joke
"Chuck Norris doesnt read books. He stares them down until he gets the information he wants."
"Time waits for no man. Unless that man is Chuck Norris."
"If you spell Chuck Norris in Scrabble, you win. Forever."
"Chuck Norris breathes air five times a day."
"In the Beginning there was nothing then Chuck Norris roundhouse kicked nothing and told it to get a job."
"Chuck Norris has a mug of nails instead of coffee in the morning."
"If Chuck Norris were to travel to an alternate dimension in which there was another Chuck Norris and they both fought, they would both win."
"The dinosaurs looked at Chuck Norris the wrong way once. You know what happened to them."
"Chuck Norris tears cure cancer. Too bad he has never cried."
"Chuck Norris once roundhouse kicked someone so hard that his foot broke the speed of light"
"Since 1940, the year Chuck Norris was born, roundhouse kick related deaths have increased 13,000 percent."
"Chuck Norris does not own a stove, oven, or microwave , because revenge is a dish best served cold."
"Chuck Norris does not sleep. He waits."
"There is no chin behind Chuck Norris beard. There is only another fist."
"The chief export of Chuck Norris is pain."
"Chuck Norris recently had the idea to sell his pee as a canned beverage. Its now called Red Bull."
"If paper beats rock, rock beats scissors, and scissors beats paper, what beats all 3 at the same time? Chuck Norris."
"On the 7th day, God rested Chuck Norris took over."
"Chuck Norris can dribble a bowling ball."
"Chuck Norris drinks napalm to fight his heartburn."
"Chuck Norris roundhouse kick is so powerful, it can be seen from outer space by the naked eye."
"If you want a list of Chuck Norris enemies, just check the extinct species list."
"Chuck Norris has never blinked in his entire life. Never."
"Chuck Norris does not use spell check. If he happens to misspell a word, Oxford will change the spelling."
"Some kids pee their name in the snow. Chuck Norris can pee his name into concrete."
"Chuck Norris counted to infinity twice."
"Chuck Norris can speak Braille."
"Chuck Norris can have both feet on the ground and kick butt at the same time."
"Chuck Norris can do a wheelie on a unicycle."
"Chuck Norris stands faster than anyone can run."
"Once a cobra bit Chuck Norris leg. After five days of excruciating pain, the cobra died."
"Chuck Norris once won a game of Connect Four in three moves."
"Champions are the breakfast of Chuck Norris."
"When the Boogeyman goes to sleep every night he checks his closet for Chuck Norris."
"Chuck Norris can slam revolving doors."
"Chuck Norris does not hunt because the word hunting implies the possibility of failure. Chuck Norris goes killing."
"The dark is afraid of Chuck Norris."
"Chuck Norris makes onions cry."
"Death once had a near-Chuck-Norris experience."
"When Chuck Norris writes, he makes paper bleed."
"Chuck Norris can strangle you with a cordless phone."
"Chuck Norris never retreats; He just attacks in the opposite direction."
"Chuck Norris can build a snowman out of rain."
"Chuck Norris can drown a fish."
"When Chuck Norris enters a room, he doesnt turn the lights on, he turns the dark off."
"The only time Chuck Norris was ever wrong was when he thought he had made a mistake."
"Chuck Norris is the only person that can punch a cyclops between the eye."
"Chuck Norris used to beat up his shadow because it was following to close. It now stands 15 feet behind him."
"Outer space exists because its afraid to be on the same planet with Chuck Norris."
"When Chuck Norris does a pushup, he's pushing the Earth down."
"Chuck Norris doesnt wear a watch. He decides what time it is."
"Chuck Norris does not get frostbite. Chuck Norris bites frost."
"Chuck Norris spices up his steaks with pepper spray."
"The Great Wall of China was originally created to keep Chuck Norris out. It didn't work."
"Chuck Norris can get in a bucket and lift it up with himself in it."
"Chuck Norris doesn't shower, he only takes blood baths."
"Chuck Norris can divide by zero."
"Chuck Norris once kicked a horse in the chin. Its descendants are now known as giraffes."
"When Chuck Norris does division, there are no remainders."
"It takes Chuck Norris 20 minutes to watch '60 Minutes'."
"Chuck Norris once went skydiving, but promised never to do it again. One Grand Canyon is enough."
"We live in an expanding universe. All of it is trying to get away from Chuck Norris."
"Chuck Norris beat the sun in a staring contest."
"Chuck Norris can clap with one hand."
"Chuck Norris doesn't need to shave. His beard is scared to grow."
"Chuck Norris invented airplanes because he was tired of being the only person that could fly."
"Freddy Krueger has nightmares about Chuck Norris."
"Chuck Norris can start a fire with an ice cube."
1 Joke
2 Chuck Norris doesnt read books. He stares them down until he gets the information he wants.
3 Time waits for no man. Unless that man is Chuck Norris.
4 If you spell Chuck Norris in Scrabble, you win. Forever.
5 Chuck Norris breathes air five times a day.
6 In the Beginning there was nothing then Chuck Norris roundhouse kicked nothing and told it to get a job.
7 Chuck Norris has a mug of nails instead of coffee in the morning.
8 If Chuck Norris were to travel to an alternate dimension in which there was another Chuck Norris and they both fought, they would both win.
9 The dinosaurs looked at Chuck Norris the wrong way once. You know what happened to them.
10 Chuck Norris tears cure cancer. Too bad he has never cried.
11 Chuck Norris once roundhouse kicked someone so hard that his foot broke the speed of light
12 Since 1940, the year Chuck Norris was born, roundhouse kick related deaths have increased 13,000 percent.
13 Chuck Norris does not own a stove, oven, or microwave , because revenge is a dish best served cold.
14 Chuck Norris does not sleep. He waits.
15 There is no chin behind Chuck Norris beard. There is only another fist.
16 The chief export of Chuck Norris is pain.
17 Chuck Norris recently had the idea to sell his pee as a canned beverage. Its now called Red Bull.
18 If paper beats rock, rock beats scissors, and scissors beats paper, what beats all 3 at the same time? Chuck Norris.
19 On the 7th day, God rested Chuck Norris took over.
20 Chuck Norris can dribble a bowling ball.
21 Chuck Norris drinks napalm to fight his heartburn.
22 Chuck Norris roundhouse kick is so powerful, it can be seen from outer space by the naked eye.
23 If you want a list of Chuck Norris enemies, just check the extinct species list.
24 Chuck Norris has never blinked in his entire life. Never.
25 Chuck Norris does not use spell check. If he happens to misspell a word, Oxford will change the spelling.
26 Some kids pee their name in the snow. Chuck Norris can pee his name into concrete.
27 Chuck Norris counted to infinity twice.
28 Chuck Norris can speak Braille.
29 Chuck Norris can have both feet on the ground and kick butt at the same time.
30 Chuck Norris can do a wheelie on a unicycle.
31 Chuck Norris stands faster than anyone can run.
32 Once a cobra bit Chuck Norris leg. After five days of excruciating pain, the cobra died.
33 Chuck Norris once won a game of Connect Four in three moves.
34 Champions are the breakfast of Chuck Norris.
35 When the Boogeyman goes to sleep every night he checks his closet for Chuck Norris.
36 Chuck Norris can slam revolving doors.
37 Chuck Norris does not hunt because the word hunting implies the possibility of failure. Chuck Norris goes killing.
38 The dark is afraid of Chuck Norris.
39 Chuck Norris makes onions cry.
40 Death once had a near-Chuck-Norris experience.
41 When Chuck Norris writes, he makes paper bleed.
42 Chuck Norris can strangle you with a cordless phone.
43 Chuck Norris never retreats; He just attacks in the opposite direction.
44 Chuck Norris can build a snowman out of rain.
45 Chuck Norris can drown a fish.
46 When Chuck Norris enters a room, he doesnt turn the lights on, he turns the dark off.
47 The only time Chuck Norris was ever wrong was when he thought he had made a mistake.
48 Chuck Norris is the only person that can punch a cyclops between the eye.
49 Chuck Norris used to beat up his shadow because it was following to close. It now stands 15 feet behind him.
50 Outer space exists because its afraid to be on the same planet with Chuck Norris.
51 When Chuck Norris does a pushup, he's pushing the Earth down.
52 Chuck Norris doesnt wear a watch. He decides what time it is.
53 Chuck Norris does not get frostbite. Chuck Norris bites frost.
54 Chuck Norris spices up his steaks with pepper spray.
55 The Great Wall of China was originally created to keep Chuck Norris out. It didn't work.
56 Chuck Norris can get in a bucket and lift it up with himself in it.
57 Chuck Norris doesn't shower, he only takes blood baths.
58 Chuck Norris can divide by zero.
59 Chuck Norris once kicked a horse in the chin. Its descendants are now known as giraffes.
60 When Chuck Norris does division, there are no remainders.
61 It takes Chuck Norris 20 minutes to watch '60 Minutes'.
62 Chuck Norris once went skydiving, but promised never to do it again. One Grand Canyon is enough.
63 We live in an expanding universe. All of it is trying to get away from Chuck Norris.
64 Chuck Norris beat the sun in a staring contest.
65 Chuck Norris can clap with one hand.
66 Chuck Norris doesn't need to shave. His beard is scared to grow.
67 Chuck Norris invented airplanes because he was tired of being the only person that could fly.
68 Freddy Krueger has nightmares about Chuck Norris.
69 Chuck Norris can start a fire with an ice cube.

View File

@@ -0,0 +1,29 @@
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
" ","P"," "," "," "," ","H"," "," "," ","R"," "," "," "," "," "," "," ","B"," "," "," "," "," ","M"
" ","O"," "," "," "," ","A"," "," "," ","E"," "," "," "," "," "," "," ","L"," "," "," "," "," ","A"
" ","W"," "," "," "," ","V"," "," "," ","D"," "," "," "," "," "," "," ","U"," "," "," "," "," ","T"
" ","E"," "," "," "," ","E"," "," "," "," "," "," "," "," "," "," "," ","E"," "," "," "," "," ","R"
" ","R"," "," "," "," "," "," "," "," ","P"," "," "," "," "," "," "," "," "," "," "," "," "," ","I"
" ","S"," "," "," "," ","F"," "," "," ","I"," "," "," "," "," "," "," ","P"," "," "," "," "," ","X"
" ","H"," "," "," "," ","U"," "," "," ","L"," "," "," "," "," "," "," ","I"," "," "," "," "," "," "
" ","E"," "," "," "," ","N"," "," "," ","L"," "," "," "," "," "," "," ","L"," "," "," "," "," "," "
" ","L"," "," "," "," "," "," "," "," ","?"," "," "," "," "," "," "," ","L"," "," "," "," "," "," "
" ","L"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","?"," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" ","R"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" ","U"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" ","L"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" ","E"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" ","S"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
1 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
2 P H R B M
3 O A E L A
4 W V D U T
5 E E E R
6 R P I
7 S F I P X
8 H U L I
9 E N L L
10 L ? L
11 L ?
12
13 R
14 U
15 L
16 E
17 S
18
19
20
21
22
23
24
25
26
27
28
29

13297
Powershell/Data/ports.csv Normal file

File diff suppressed because it is too large Load Diff

217
Powershell/Data/scripts.csv Normal file
View File

@@ -0,0 +1,217 @@
Script,Description
add-firewall-rules.ps1, adds firewall rules to the given executables (needs admin rights)
add-memo.ps1, adds the given memo text to $HOME/Memos.csv
cd-desktop.ps1, go to the user's desktop folder
cd-docs.ps1, go to the user's documents folder
cd-downloads.ps1, go to the user's downloads folder
cd-dropbox.ps1, go to the user's Dropbox folder
cd-home.ps1, go to the user's home folder
cd-music.ps1, go to the user's music folder
cd-onedrive.ps1, go to the user's OneDrive folder
cd-pics.ps1, go to the user's pictures folder
cd-recycle-bin.ps1, go to the user's recycle bin folder
cd-repos.ps1, go to the user's Git repositories folder
cd-root.ps1, go to the root directory (C: on Windows)
cd-scripts.ps1, go to the PowerShell Scripts folder
cd-up.ps1, go one directory level up
cd-up2.ps1, go two directory levels up
cd-up3.ps1, go three directory levels up
cd-up4.ps1, go four directory levels up
cd-videos.ps1, go to the user's videos folder
check-cpu-temp.ps1, checks the CPU temperature
check-dns-resolution.ps1, checks the DNS resolution with frequently used domain names
check-drive-space.ps1, checks the given drive for free space left
check-file-system.ps1, checks the validity of the file system (needs admin rights)
check-health.ps1, checks the system health
check-ipv4-address.ps1, checks the given IPv4 address for validity
check-ipv6-address.ps1, checks the given IPv6 address for validity
check-mac-address.ps1, checks the given MAC address for validity
check-ping.ps1, checks the ping latency to the internet
check-swap-space.ps1, checks the swap space for free space left
check-symlinks.ps1, checks every symlink in the given directory tree
check-weather.ps1, checks the current weather for critical values
check-windows-system-files.ps1, checks the validity of the Windows system files
check-xml-file.ps1, checks the given XML file for validity
cherry-picker.ps1, cherry-picks a Git commit into multiple branches
clean-repo.ps1, cleans the current/given Git repository from untracked files (including submodules)
clean-repos.ps1, cleans all Git repositories under the current/given directory from untracked files (including submodules)
clear-recycle-bin.ps1, removes the content of the recycle bin folder (can not be undo!)
clone-repos.ps1, clones well-known Git repositories
close-calculator.ps1, closes the calculator program gracefully
close-chrome.ps1, closes Google Chrome gracefully
close-cortana.ps1, closes Cortana gracefully
close-edge.ps1, closes Microsoft Edge gracefully
close-file-explorer.ps1, closes Microsoft File Explorer gracefully
close-program.ps1, closes the given program gracefully
close-system-settings.ps1, closes the System Settings gracefully
close-thunderbird.ps1, closes Mozilla Thunderbird gracefully
close-vlc.ps1, closes the VLC media player gracefully
close-windows-terminal.ps1, closes Windows Terminal gracefully
configure-git.ps1, sets up the Git user configuration
convert-csv2txt.ps1, converts the given CSV file into a text list
convert-mysql2csv.ps1, converts the MySQL database table to a CSV file
convert-ps2bat.ps1, converts PowerShell script(s) to .bat files
convert-sql2csv.ps1, converts the SQL database table to a CSV file
convert-txt2wav.ps1, converts text into a audio .WAV file
create-branch.ps1, creates a new branch in the current/given Git repository
create-shortcut.ps1, creates a shortcut
create-symlink.ps1, creates a symbolic link
create-tag.ps1, creates a new tag in the current/given Git repository
daily-tasks.sh, execute PowerShell scripts automatically as daily tasks (Linux only)
decrypt-file.ps1, decrypts the given file
display-time.ps1, displays the current time for 10 seconds by default
download-dir.ps1, downloads a directory tree from the given URL
download-file.ps1, downloads a file from the given URL
edit.ps1, edits the given file with the built-in text editor
enable-crash-dumps.ps1, enables the writing of crash dumps
enable-god-mode.ps1, enables the god mode (adds a new icon to the desktop)
enable-ssh-client.ps1, enables the SSH client (needs admin rights)
enable-ssh-server.ps1, enables the SSH server (needs admin rights)
encrypt-file.ps1, encrypts the given file
fetch-repo.ps1, fetches updates for the current/given Git repository (including submodules)
fetch-repos.ps1, fetches updates for all Git repositories under the current/given directory (including submodules)
generate-qrcode.ps1, generates a QR code
hibernate.ps1, enables hibernate mode for the local computer (needs admin rights)
inspect-exe.ps1, prints basic information of the given executable file
install-google-chrome.ps1, installs the Google Chrome browser
install-signal-cli.ps1, installs signal-cli from github.com/AsamK/signal-cli
introduce-powershell.ps1, introduces PowerShell to new users
list-aliases.ps1, lists all PowerShell aliases
list-anagrams.ps1, lists all anagrams of the given word
list-automatic-variables.ps1, lists the automatic variables of PowerShell
list-branches.ps1, lists all branches in the current/given Git repository
list-cheat-sheet.ps1, lists the PowerShell cheat sheet
list-city-weather.ps1, lists the current weather of cities worldwide (east to west)
list-commits.ps1, lists all commits in the current/given Git repository
list-clipboard.ps1, lists the contents of the clipboard
list-credits.ps1, shows the credits
list-dir.ps1, lists the directory content (formatted in columns)
list-dir-tree.ps1, lists the directory tree content
list-drives.ps1, lists all drives
list-environment-variables.ps1, lists all environment variables
list-emojis.ps1, lists the emojis of Unicode 13.0
list-empty-dirs.ps1, lists empty subfolders within the given directory tree
list-empty-files.ps1, lists empty files within the given directory tree
list-files.ps1, lists all files in the given folder and also in every subfolder
list-fritzbox-calls.ps1, lists the FRITZ!Box calls
list-fritzbox-devices.ps1, lists FRITZ!Box's known devices
list-hidden-files.ps1, lists hidden files within the given directory tree
list-installed-apps.ps1, lists the installed Windows Store apps
list-installed-software.ps1, lists the installed software (except Windows Store apps)
list-latest-tag.ps1, lists the latest tag on the current branch in a Git repository
list-memos.ps1, lists the memos at $HOME/Memos.csv
list-unused-files.ps1, lists unused files in a directory tree
list-cmdlets.ps1, lists the PowerShell cmdlets
list-earthquakes.ps1, lists earthquakes with magnitude >= 6.0 for the last 30 days
list-modules.ps1, lists the PowerShell modules
list-mysql-tables.ps1, lists the MySQL server tables
list-network-shares.ps1, lists the network shares of the local computer
list-news.ps1, lists the latest news
list-os-releases.ps1, lists operating system releases and download URL
list-os-updates.ps1, lists operating system updates
list-printers.ps1, lists all printer known to the computer
list-processes.ps1, lists the local computer processes
list-profiles.ps1, lists your PowerShell profiles
list-random-passwords.ps1, prints a list of random passwords
list-random-pins.ps1, prints a list of random PIN's
list-recycle-bin.ps1, lists the content of the recycle bin folder
list-scripts.ps1, lists all PowerShell scripts in this repository
list-services.ps1, lists the services on the local computer
list-sql-tables.ps1, lists the SQL server tables
list-submodules.ps1, lists the submodules of the current/given Git repository
list-system-info.ps1, lists system information on the local computer
list-tags.ps1, lists all tags in the current/given Git repository
list-tasks.ps1, lists all Windows scheduler tasks
list-timezone.ps1, lists the current time zone details
list-timezones.ps1, lists all time zones available
list-tiobe-index.ps1, lists the TIOBE index of top programming languages
list-user-groups.ps1, lists the user groups on the local computer
list-weather.ps1, lists the hourly weather
list-workdir.ps1, lists the current working directory
locate-city.ps1, prints the geographic location of the given city
locate-ipaddress.ps1, prints the geographic location of the given IP address
locate-zip-code.ps1, prints the geographic location of the given zip-code
MD5.ps1, prints the MD5 checksum of the given file
make-install.ps1, installs built executables and libs to the installation directory
make-repo.ps1, builds the current/given Git repository
make-repos.ps1, builds all Git repositories under the current/given directory
moon.ps1, prints the current moon phase
mute-audio.ps1, mutes audio
next-joke.ps1], gets the next random Juck Norris joke
open-browser.ps1, starts the default Web browser
open-calculator.ps1, starts the calculator program
open-email-client.ps1, starts the default email client
open-file-explorer.ps1, starts the Microsoft File Explorer
open-recycle-bin.ps1, starts the File Explorer with the recycle bin folder
play-beep.ps1, plays a beep sound
play-files.ps1, plays the given audio files
play-mission-impossible.ps1, plays the Mission Impossible theme
play-m3u.ps1, plays the given playlist (M3U file format)
play-mp3.ps1, plays the given sound file (MP3 file format)
play-super-mario.ps1, plays the Super Mario Intro
play-the-imperial-march.ps1, plays the Imperial March (Star Wars)
poweroff.ps1, halts the local computer (needs admin rights)
pull-repo.ps1, pulls updates for the current/given Git repository (including submodules)
pull-repos.ps1, pulls updates for all Git repositories under the current/given directory (including submodules)
query-smart-data.ps1, queries the S.M.A.R.T. data of your HDD/SSD's and saves it to the current/given directory
new-email.ps1, starts the default email client to write a new email
reboot.ps1, reboots the local computer (needs admin rights)
reboot-fritzbox.ps1, reboots the FRITZ!box device
remove-empty-dirs.ps1, removes empty subfolders within the given directory tree
search-filename.ps1, searches the directory tree for filenames by given pattern
search-files.ps1, searches the given pattern in the given files
scan-ports.ps1, scans the network for open/closed ports
send-email.ps1, sends an email message
send-tcp.ps1, sends a TCP message to the given IP address and port
send-udp.ps1, sends a UDP datagram message to the given IP address and port
set-profile.ps1, updates your PowerShell user profile
set-timer.ps1, sets a timer for a countdown
set-wallpaper.ps1, sets the given image as wallpaper
SHA1.ps1, prints the SHA1 checksum of the given file
SHA256.ps1, prints the SHA256 checksum of the given file
simulate-matrix.ps1, simulates the Matrix (fun)
simulate-presence.ps1, simulates the human presence against burglars
speak-checklist.ps1, speaks the given checklist by text-to-speech (TTS)
speak-countdown.ps1, starts a countdown by text-to-speech (TTS)
speak-date.ps1, speaks the current date by text-to-speech (TTS)
speak-english.ps1, speaks the given text with an English text-to-speech (TTS) voice
speak-epub.ps1, speaks the content of the given Epub file by text-to-speech (TTS)
speak-file.ps1, speaks the content of the given text file by text-to-speech (TTS)
speak-german.ps1, speaks the given text with a German text-to-speech (TTS) voice
speak-joke.ps1, speaks the next joke by text-to-speech (TTS)
speak-test.ps1, performs a speak test by text-to-speech (TTS)
speak-text.ps1, speaks the given text by text-to-speech (TTS)
speak-time.ps1, speaks the current time by text-to-speech (TTS)
start-ipfs-server.ps1, starts a local IPFS server
switch-branch.ps1, switches the branch in the current/given Git repository (including submodules)
switch-shelly1.ps1, switches a Shelly1 device in the local network
sync-repo.ps1, synchronizes a Git repository by push & pull (including submodules)
take-screenshot.ps1, takes a single screenshot
take-screenshots.ps1, takes multiple screenshots
translate-file.ps1, translates the given text file into another language
translate-files.ps1, translates the given text files into any supported language
translate-text.ps1, translates the given text into other languages
turn-volume-up.ps1, turns the audio volume up (+10% by default)
turn-volume-down.ps1, turns the audio volume down (-10% by default)
unmute-audio.ps1, unmutes audio
upload-file.ps1, uploads the local file to the given FTP server
voice-control.ps1, executes the PowerShell scripts by voice
wakeup.ps1, sends a magic packet to the given computer, waking him up
weather.ps1, prints the current weather forecast
weather-report.ps1, prints the local weather report
what-is.ps1, prints a description of the given abbreviation
write-animated.ps1, writes animated text
write-big.ps1, writes the given text in big letters
write-blue.ps1, writes the given text in a blue foreground color
write-braille.ps1, writes the given text in Braille
write-green.ps1, writes the given text in a green foreground color
write-lowercase.ps1, writes the given text in lowercase letters
write-marquee.ps1, writes the given text as marquee
write-morse-code.ps1, writes the given text in Morse code
write-motd.ps1, writes the message of the day (MOTD)
write-red.ps1, writes the given text in a red foreground color
write-rot13.ps1, encodes or decodes the given text with ROT13
write-typewriter.ps1, writes the given text with the typewriter effect
write-uppercase.ps1, writes the given text in uppercase letters
write-vertical.ps1, writes the given text in vertical direction
zip-dir.ps1, creates a zip archive of the given directory
1 Script Description
2 add-firewall-rules.ps1 adds firewall rules to the given executables (needs admin rights)
3 add-memo.ps1 adds the given memo text to $HOME/Memos.csv
4 cd-desktop.ps1 go to the user's desktop folder
5 cd-docs.ps1 go to the user's documents folder
6 cd-downloads.ps1 go to the user's downloads folder
7 cd-dropbox.ps1 go to the user's Dropbox folder
8 cd-home.ps1 go to the user's home folder
9 cd-music.ps1 go to the user's music folder
10 cd-onedrive.ps1 go to the user's OneDrive folder
11 cd-pics.ps1 go to the user's pictures folder
12 cd-recycle-bin.ps1 go to the user's recycle bin folder
13 cd-repos.ps1 go to the user's Git repositories folder
14 cd-root.ps1 go to the root directory (C: on Windows)
15 cd-scripts.ps1 go to the PowerShell Scripts folder
16 cd-up.ps1 go one directory level up
17 cd-up2.ps1 go two directory levels up
18 cd-up3.ps1 go three directory levels up
19 cd-up4.ps1 go four directory levels up
20 cd-videos.ps1 go to the user's videos folder
21 check-cpu-temp.ps1 checks the CPU temperature
22 check-dns-resolution.ps1 checks the DNS resolution with frequently used domain names
23 check-drive-space.ps1 checks the given drive for free space left
24 check-file-system.ps1 checks the validity of the file system (needs admin rights)
25 check-health.ps1 checks the system health
26 check-ipv4-address.ps1 checks the given IPv4 address for validity
27 check-ipv6-address.ps1 checks the given IPv6 address for validity
28 check-mac-address.ps1 checks the given MAC address for validity
29 check-ping.ps1 checks the ping latency to the internet
30 check-swap-space.ps1 checks the swap space for free space left
31 check-symlinks.ps1 checks every symlink in the given directory tree
32 check-weather.ps1 checks the current weather for critical values
33 check-windows-system-files.ps1 checks the validity of the Windows system files
34 check-xml-file.ps1 checks the given XML file for validity
35 cherry-picker.ps1 cherry-picks a Git commit into multiple branches
36 clean-repo.ps1 cleans the current/given Git repository from untracked files (including submodules)
37 clean-repos.ps1 cleans all Git repositories under the current/given directory from untracked files (including submodules)
38 clear-recycle-bin.ps1 removes the content of the recycle bin folder (can not be undo!)
39 clone-repos.ps1 clones well-known Git repositories
40 close-calculator.ps1 closes the calculator program gracefully
41 close-chrome.ps1 closes Google Chrome gracefully
42 close-cortana.ps1 closes Cortana gracefully
43 close-edge.ps1 closes Microsoft Edge gracefully
44 close-file-explorer.ps1 closes Microsoft File Explorer gracefully
45 close-program.ps1 closes the given program gracefully
46 close-system-settings.ps1 closes the System Settings gracefully
47 close-thunderbird.ps1 closes Mozilla Thunderbird gracefully
48 close-vlc.ps1 closes the VLC media player gracefully
49 close-windows-terminal.ps1 closes Windows Terminal gracefully
50 configure-git.ps1 sets up the Git user configuration
51 convert-csv2txt.ps1 converts the given CSV file into a text list
52 convert-mysql2csv.ps1 converts the MySQL database table to a CSV file
53 convert-ps2bat.ps1 converts PowerShell script(s) to .bat files
54 convert-sql2csv.ps1 converts the SQL database table to a CSV file
55 convert-txt2wav.ps1 converts text into a audio .WAV file
56 create-branch.ps1 creates a new branch in the current/given Git repository
57 create-shortcut.ps1 creates a shortcut
58 create-symlink.ps1 creates a symbolic link
59 create-tag.ps1 creates a new tag in the current/given Git repository
60 daily-tasks.sh execute PowerShell scripts automatically as daily tasks (Linux only)
61 decrypt-file.ps1 decrypts the given file
62 display-time.ps1 displays the current time for 10 seconds by default
63 download-dir.ps1 downloads a directory tree from the given URL
64 download-file.ps1 downloads a file from the given URL
65 edit.ps1 edits the given file with the built-in text editor
66 enable-crash-dumps.ps1 enables the writing of crash dumps
67 enable-god-mode.ps1 enables the god mode (adds a new icon to the desktop)
68 enable-ssh-client.ps1 enables the SSH client (needs admin rights)
69 enable-ssh-server.ps1 enables the SSH server (needs admin rights)
70 encrypt-file.ps1 encrypts the given file
71 fetch-repo.ps1 fetches updates for the current/given Git repository (including submodules)
72 fetch-repos.ps1 fetches updates for all Git repositories under the current/given directory (including submodules)
73 generate-qrcode.ps1 generates a QR code
74 hibernate.ps1 enables hibernate mode for the local computer (needs admin rights)
75 inspect-exe.ps1 prints basic information of the given executable file
76 install-google-chrome.ps1 installs the Google Chrome browser
77 install-signal-cli.ps1 installs signal-cli from github.com/AsamK/signal-cli
78 introduce-powershell.ps1 introduces PowerShell to new users
79 list-aliases.ps1 lists all PowerShell aliases
80 list-anagrams.ps1 lists all anagrams of the given word
81 list-automatic-variables.ps1 lists the automatic variables of PowerShell
82 list-branches.ps1 lists all branches in the current/given Git repository
83 list-cheat-sheet.ps1 lists the PowerShell cheat sheet
84 list-city-weather.ps1 lists the current weather of cities worldwide (east to west)
85 list-commits.ps1 lists all commits in the current/given Git repository
86 list-clipboard.ps1 lists the contents of the clipboard
87 list-credits.ps1 shows the credits
88 list-dir.ps1 lists the directory content (formatted in columns)
89 list-dir-tree.ps1 lists the directory tree content
90 list-drives.ps1 lists all drives
91 list-environment-variables.ps1 lists all environment variables
92 list-emojis.ps1 lists the emojis of Unicode 13.0
93 list-empty-dirs.ps1 lists empty subfolders within the given directory tree
94 list-empty-files.ps1 lists empty files within the given directory tree
95 list-files.ps1 lists all files in the given folder and also in every subfolder
96 list-fritzbox-calls.ps1 lists the FRITZ!Box calls
97 list-fritzbox-devices.ps1 lists FRITZ!Box's known devices
98 list-hidden-files.ps1 lists hidden files within the given directory tree
99 list-installed-apps.ps1 lists the installed Windows Store apps
100 list-installed-software.ps1 lists the installed software (except Windows Store apps)
101 list-latest-tag.ps1 lists the latest tag on the current branch in a Git repository
102 list-memos.ps1 lists the memos at $HOME/Memos.csv
103 list-unused-files.ps1 lists unused files in a directory tree
104 list-cmdlets.ps1 lists the PowerShell cmdlets
105 list-earthquakes.ps1 lists earthquakes with magnitude >= 6.0 for the last 30 days
106 list-modules.ps1 lists the PowerShell modules
107 list-mysql-tables.ps1 lists the MySQL server tables
108 list-network-shares.ps1 lists the network shares of the local computer
109 list-news.ps1 lists the latest news
110 list-os-releases.ps1 lists operating system releases and download URL
111 list-os-updates.ps1 lists operating system updates
112 list-printers.ps1 lists all printer known to the computer
113 list-processes.ps1 lists the local computer processes
114 list-profiles.ps1 lists your PowerShell profiles
115 list-random-passwords.ps1 prints a list of random passwords
116 list-random-pins.ps1 prints a list of random PIN's
117 list-recycle-bin.ps1 lists the content of the recycle bin folder
118 list-scripts.ps1 lists all PowerShell scripts in this repository
119 list-services.ps1 lists the services on the local computer
120 list-sql-tables.ps1 lists the SQL server tables
121 list-submodules.ps1 lists the submodules of the current/given Git repository
122 list-system-info.ps1 lists system information on the local computer
123 list-tags.ps1 lists all tags in the current/given Git repository
124 list-tasks.ps1 lists all Windows scheduler tasks
125 list-timezone.ps1 lists the current time zone details
126 list-timezones.ps1 lists all time zones available
127 list-tiobe-index.ps1 lists the TIOBE index of top programming languages
128 list-user-groups.ps1 lists the user groups on the local computer
129 list-weather.ps1 lists the hourly weather
130 list-workdir.ps1 lists the current working directory
131 locate-city.ps1 prints the geographic location of the given city
132 locate-ipaddress.ps1 prints the geographic location of the given IP address
133 locate-zip-code.ps1 prints the geographic location of the given zip-code
134 MD5.ps1 prints the MD5 checksum of the given file
135 make-install.ps1 installs built executables and libs to the installation directory
136 make-repo.ps1 builds the current/given Git repository
137 make-repos.ps1 builds all Git repositories under the current/given directory
138 moon.ps1 prints the current moon phase
139 mute-audio.ps1 mutes audio
140 next-joke.ps1] gets the next random Juck Norris joke
141 open-browser.ps1 starts the default Web browser
142 open-calculator.ps1 starts the calculator program
143 open-email-client.ps1 starts the default email client
144 open-file-explorer.ps1 starts the Microsoft File Explorer
145 open-recycle-bin.ps1 starts the File Explorer with the recycle bin folder
146 play-beep.ps1 plays a beep sound
147 play-files.ps1 plays the given audio files
148 play-mission-impossible.ps1 plays the Mission Impossible theme
149 play-m3u.ps1 plays the given playlist (M3U file format)
150 play-mp3.ps1 plays the given sound file (MP3 file format)
151 play-super-mario.ps1 plays the Super Mario Intro
152 play-the-imperial-march.ps1 plays the Imperial March (Star Wars)
153 poweroff.ps1 halts the local computer (needs admin rights)
154 pull-repo.ps1 pulls updates for the current/given Git repository (including submodules)
155 pull-repos.ps1 pulls updates for all Git repositories under the current/given directory (including submodules)
156 query-smart-data.ps1 queries the S.M.A.R.T. data of your HDD/SSD's and saves it to the current/given directory
157 new-email.ps1 starts the default email client to write a new email
158 reboot.ps1 reboots the local computer (needs admin rights)
159 reboot-fritzbox.ps1 reboots the FRITZ!box device
160 remove-empty-dirs.ps1 removes empty subfolders within the given directory tree
161 search-filename.ps1 searches the directory tree for filenames by given pattern
162 search-files.ps1 searches the given pattern in the given files
163 scan-ports.ps1 scans the network for open/closed ports
164 send-email.ps1 sends an email message
165 send-tcp.ps1 sends a TCP message to the given IP address and port
166 send-udp.ps1 sends a UDP datagram message to the given IP address and port
167 set-profile.ps1 updates your PowerShell user profile
168 set-timer.ps1 sets a timer for a countdown
169 set-wallpaper.ps1 sets the given image as wallpaper
170 SHA1.ps1 prints the SHA1 checksum of the given file
171 SHA256.ps1 prints the SHA256 checksum of the given file
172 simulate-matrix.ps1 simulates the Matrix (fun)
173 simulate-presence.ps1 simulates the human presence against burglars
174 speak-checklist.ps1 speaks the given checklist by text-to-speech (TTS)
175 speak-countdown.ps1 starts a countdown by text-to-speech (TTS)
176 speak-date.ps1 speaks the current date by text-to-speech (TTS)
177 speak-english.ps1 speaks the given text with an English text-to-speech (TTS) voice
178 speak-epub.ps1 speaks the content of the given Epub file by text-to-speech (TTS)
179 speak-file.ps1 speaks the content of the given text file by text-to-speech (TTS)
180 speak-german.ps1 speaks the given text with a German text-to-speech (TTS) voice
181 speak-joke.ps1 speaks the next joke by text-to-speech (TTS)
182 speak-test.ps1 performs a speak test by text-to-speech (TTS)
183 speak-text.ps1 speaks the given text by text-to-speech (TTS)
184 speak-time.ps1 speaks the current time by text-to-speech (TTS)
185 start-ipfs-server.ps1 starts a local IPFS server
186 switch-branch.ps1 switches the branch in the current/given Git repository (including submodules)
187 switch-shelly1.ps1 switches a Shelly1 device in the local network
188 sync-repo.ps1 synchronizes a Git repository by push & pull (including submodules)
189 take-screenshot.ps1 takes a single screenshot
190 take-screenshots.ps1 takes multiple screenshots
191 translate-file.ps1 translates the given text file into another language
192 translate-files.ps1 translates the given text files into any supported language
193 translate-text.ps1 translates the given text into other languages
194 turn-volume-up.ps1 turns the audio volume up (+10% by default)
195 turn-volume-down.ps1 turns the audio volume down (-10% by default)
196 unmute-audio.ps1 unmutes audio
197 upload-file.ps1 uploads the local file to the given FTP server
198 voice-control.ps1 executes the PowerShell scripts by voice
199 wakeup.ps1 sends a magic packet to the given computer waking him up
200 weather.ps1 prints the current weather forecast
201 weather-report.ps1 prints the local weather report
202 what-is.ps1 prints a description of the given abbreviation
203 write-animated.ps1 writes animated text
204 write-big.ps1 writes the given text in big letters
205 write-blue.ps1 writes the given text in a blue foreground color
206 write-braille.ps1 writes the given text in Braille
207 write-green.ps1 writes the given text in a green foreground color
208 write-lowercase.ps1 writes the given text in lowercase letters
209 write-marquee.ps1 writes the given text as marquee
210 write-morse-code.ps1 writes the given text in Morse code
211 write-motd.ps1 writes the message of the day (MOTD)
212 write-red.ps1 writes the given text in a red foreground color
213 write-rot13.ps1 encodes or decodes the given text with ROT13
214 write-typewriter.ps1 writes the given text with the typewriter effect
215 write-uppercase.ps1 writes the given text in uppercase letters
216 write-vertical.ps1 writes the given text in vertical direction
217 zip-dir.ps1 creates a zip archive of the given directory

View File

@@ -0,0 +1,21 @@
This license is a legal document designed to protect your rights and the rights of the Pareto Software, LLC, the owner of Simplemaps.com. Please read it carefully. Purchasing or downloading a data product constitutes acceptance of this license.
Description of Product and Parties: This license is a contract between you (hereafter, the Customer) and Pareto Software, LLC (hereafter, the Provider) regarding the use and/or sale of an collection of geographic data (hereafter, the Database).
Ownership of Database: All rights to the Database are owned by the Provider. The Database is a cleaned and curated collection of geographic facts and the Provider retains all rights to the Database afforded by the law. Ownership of any intellectual property generated by the Provider while performing custom modifications to the Database for a Customer (with or without payment) is retained by the Provider.
License: Customers who purchase a license are allowed to use the database for projects that benefit their organization or that their organization oversees. Attribution is not required. The Customer is allowed to query the database to power privately or publicly facing applications. The Customer is allowed to make copies and backups of the data. The Customer may not publicly redistribute the Database without prior written permission. Customers can transfer their license to a third-party, at the sole discretion of the Provider, by submitting a request via email.
Free US Zip Code Database: The Provider offers a free version of the US Zip Code Database. This Database is offered free of charge conditional on a link back to https://simplemaps.com/data/us-zips. This backlink must come from a public webpage where the Customer is using the data. If the Customer uses the data internally, the backlink must be placed on the organization's website on a page that can be easily found though links on the root domain. The link must be clearly visible to the human eye. The backlink must be placed before the Customer uses the Database in production.
Free US Cities Database: The Provider offers a free version of the US Cities Database. This Database is offered free of charge conditional on a link back to https://simplemaps.com/data/us-cities. This backlink must come from a public webpage where the Customer is using the data. If the Customer uses the data internally, the backlink must be placed on the organization's website on a page that can be easily found though links on the root domain. The link must be clearly visible to the human eye. The backlink must be placed before the Customer uses the Database in production.
Basic World Cities Database: The Provider offers a Basic World Cities Database free of charge. This database is licensed under the Creative Commons Attribution 4.0 license as described at: https://creativecommons.org/licenses/by/4.0/.
Comprehensive and Pro World Cities Database Density Data: The Comprehensive and Pro World Cities Databases includes density estimates from The Center for International Earth Science Information Network - CIESIN - Columbia University. 2016. Gridded Population of the World, Version 4 (GPWv4): Population Count. Palisades, NY: NASA Socioeconomic Data and Applications Center (SEDAC). http://dx.doi.org/10.7927/H4X63JVC. Accessed June 2017. The density estimates are include under the Creative Commons Attribution 4.0 International License. The Provider places no additional restrictions on the use or distribution of the density data.
Guarantee: The Provider guarantees that for the period of thirty (30) days from the purchase of a License that the Customer shall, upon request, be refunded their actual purchase price within a reasonable period of time. The Customer acknowledges that receipt of a refund constitutes a termination of their License to use the Database. In the event of a Refund, the Customer promises to delete the Database immediately. Refunds after the period of thirty (30) days shall be at the sole discretion of the Provider.
LIMITATION OF LIABILITY: THE DATABASE IS SOLD "AS IS" AND "WITH ALL FAULTS". THE PROVIDER MAKES NO WARRANTY THAT IT IS FREE OF DEFECTS OR IS SUITABLE FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE PROVIDER BE RESPONSIBLE FOR LOSS OR DAMAGES ARRISING FROM THE INSTALLATION OR USE OF THE DATABASE, INCLUDING BUT NOT LIMITED TO ANY INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES. THE CUSTOMER IS SOLELY RESPONSIBLE FOR ENSURING THAT THEIR USE OF THE DATABASE IS IN ACCORDANCE WITH THE LAW OF THEIR JURISDICTION.
PROHIBITION OF ILLEGAL USE: USE OF THE DATABASE WHICH IS CONTRARY TO THE LAW IS PROHIBITED, AND IMMEDIATELY TERMINATES THE CUSTOMER'S LICENSE TO USE THE DATABASE.

File diff suppressed because it is too large Load Diff

1129901
Powershell/Data/zip-codes.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
Set-ExecutionPolicy RemoteSigned
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session

View File

@@ -0,0 +1 @@
Remove-PSSession $Session

View File

@@ -0,0 +1,487 @@
@echo off
cls
echo.
ECHO ===============================================================================
echo Paste or write the complete path to install.esd or install.wim file
echo ^(without quotes marks "" even if the path contains spaces^)
ECHO ===============================================================================
echo.
set /p WIMFILE=
if "%WIMFILE%"=="" echo Incorrect file name or path&echo.&PAUSE&GOTO :QUIT
title ESD ^<^> WIM
color 1f
%windir%\system32\reg.exe query "HKU\S-1-5-19" >nul 2>&1 || (
echo -------
echo *** WARNING ***
echo -------
echo.
echo.
echo ADMINISTRATOR PRIVILEGES NOT DETECTED
echo ____________________________________________________________________________
echo.
echo This script require administrator privileges.
echo.
echo To do so, right click on this script and select 'Run as administrator'
echo.
echo.
echo.
echo Press any key to exit...
pause >nul
goto :eof
)
cd /d "%~dp0"
if exist "%CD%\dism\dism.exe" set Path=%CD%\dism;%Path%
SET ERRORTEMP=
set /A count=0
dism /get-wiminfo /wimfile:"%WIMFILE%" >nul 2>&1 || (
echo.
echo Incorrect file name or path
echo.
echo Press any key to exit.
pause >nul
goto :eof
)
setlocal EnableDelayedExpansion
FOR /F "tokens=2 delims=: " %%i IN ('dism /english /Get-WimInfo /WimFile:"%WIMFILE%" ^| findstr "Index"') DO SET images=%%i
for /L %%i in (1, 1, %images%) do call :setcount %%i
if "%WIMFILE:~-3%"=="esd" GOTO :ESDMENU
if "%WIMFILE:~-3%"=="wim" GOTO :WIMMENU
exit
:setcount
set /A count+=1
for /f "tokens=1* delims=: " %%i in ('dism /english /get-wiminfo /wimfile:"%WIMFILE%" /index:%1 ^| find /i "Name"') do set name%count%="%%j"
goto :eof
:ESDMENU
cls
ECHO ===============================================================================
ECHO. Detected ESD file contains %images% indexes:
ECHO.
for /L %%i in (1, 1, %images%) do (
ECHO. %%i. !name%%i!
)
ECHO.
ECHO ===============================================================================
ECHO. Options:
ECHO ===============================================================================
ECHO. 1 - Export 1st index
ECHO. 2 - Export all indexes
ECHO. 3 - Export selected single index
ECHO. 4 - Export selected range of indexes
ECHO ===============================================================================
ECHO. Press 'Q' to Quit
ECHO ===============================================================================
choice /c 1234q /n /m "Choose a menu option, or Q to quit: "
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP%==1 GOTO :ESD1
IF %ERRORTEMP%==2 GOTO :ESD2
IF %ERRORTEMP%==3 GOTO :ESD3
IF %ERRORTEMP%==4 GOTO :ESD4
IF %ERRORTEMP%==5 GOTO :QUIT
GOTO :MAINMENU
:ESD1
cls
IF EXIST "%CD%\install.wim" (
ECHO ===============================================================================
ECHO. An install.wim file is already present in the current folder.
ECHO ===============================================================================
ECHO.
echo Press any key to exit.
pause >nul
GOTO :QUIT
)
ECHO ===============================================================================
Echo Exporting ESD Index 1 to a new install.wim file...
ECHO ===============================================================================
mkdir temp
dism /Quiet /Capture-Image /ImageFile:install.wim /CaptureDir:.\temp /Name:container /Compress:max /CheckIntegrity
rmdir /s /q temp
dism /Export-Image /SourceImageFile:"%WIMFILE%" /SourceIndex:1 /DestinationImageFile:install.wim /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
dism /Quiet /Delete-Image /ImageFile:install.wim /Index:1 /CheckIntegrity
echo.
echo Done.
echo.
echo Press any key to exit.
pause >nul
GOTO :QUIT
:ESD2
cls
IF EXIST "%CD%\install.wim" (
ECHO ===============================================================================
ECHO. An install.wim file is already present in the current folder.
ECHO ===============================================================================
ECHO.
echo Press any key to exit.
pause >nul
GOTO :QUIT
)
ECHO ===============================================================================
Echo Exporting ESD Index 1 to a new install.wim file...
ECHO ===============================================================================
mkdir temp
dism /Quiet /Capture-Image /ImageFile:install.wim /CaptureDir:.\temp /Name:container /Compress:max /CheckIntegrity
rmdir /s /q temp
dism /Export-Image /SourceImageFile:"%WIMFILE%" /SourceIndex:1 /DestinationImageFile:install.wim /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
dism /Quiet /Delete-Image /ImageFile:install.wim /Index:1 /CheckIntegrity
if "%images%"=="1" (
echo.
echo Done.
echo.
echo Press any key to exit.
pause >nul
GOTO :QUIT
)
for /L %%i in (2, 1, %images%) do (
ECHO.
ECHO ===============================================================================
Echo Exporting ESD Index %%i to install.wim file...
ECHO ===============================================================================
dism /Export-Image /SourceImageFile:"%WIMFILE%" /SourceIndex:%%i /DestinationImageFile:install.wim /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
)
echo.
echo Done.
echo.
echo Press any key to exit.
pause >nul
GOTO :QUIT
:ESD3
cls
set _index=
ECHO ===============================================================================
ECHO. Detected ESD file contains %images% indexes:
ECHO.
for /L %%i in (1, 1, %images%) do (
ECHO. %%i. !name%%i!
)
ECHO.
ECHO ===============================================================================
ECHO. Enter desired index number to export
ECHO ===============================================================================
ECHO. Enter zero '0' to go back to Main Menu
ECHO ===============================================================================
set /p _index= ^>
if /i "%_index%"=="0" goto :ESDMENU
if [%_index%]==[] goto :ESD3
if /i %_index% GTR %images% echo.&echo Selected number is higher than available indexes&echo.&PAUSE&goto :ESD3
cls
IF EXIST "%CD%\install.wim" (
ECHO ===============================================================================
ECHO. An install.wim file is already present in the current folder.
ECHO ===============================================================================
ECHO.
echo Press any key to exit.
pause >nul
GOTO :QUIT
)
ECHO ===============================================================================
Echo Exporting ESD Index %_index% to a new install.wim file...
ECHO ===============================================================================
mkdir temp
dism /Quiet /Capture-Image /ImageFile:install.wim /CaptureDir:.\temp /Name:container /Compress:max /CheckIntegrity
rmdir /s /q temp
dism /Export-Image /SourceImageFile:"%WIMFILE%" /SourceIndex:%_index% /DestinationImageFile:install.wim /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
dism /Quiet /Delete-Image /ImageFile:install.wim /Index:1 /CheckIntegrity
echo.
echo Done.
echo.
echo Press any key to exit.
pause >nul
GOTO :QUIT
:ESD4
cls
set _range=
set _start=
set _end=
ECHO ===============================================================================
ECHO. Detected ESD file contains %images% indexes:
ECHO.
for /L %%i in (1, 1, %images%) do (
ECHO. %%i. !name%%i!
)
ECHO.
ECHO ===============================================================================
ECHO. Enter desired Range of indexes to export: Start-End
ECHO. Example: 2-4 or 1-3 or 3-4
ECHO ===============================================================================
ECHO. Enter zero '0' to go back to Main Menu
ECHO ===============================================================================
set /p _range= ^>
if /i "%_range%"=="0" goto :ESDMENU
if [%_range%]==[] goto :ESD4
for /f "tokens=1 delims=-" %%i in ('echo %_range%') do set _start=%%i
for /f "tokens=2 delims=-" %%i in ('echo %_range%') do set _end=%%i
if /i %_start% GTR %images% echo.&echo Range Start is higher than available indexes&echo.&PAUSE&goto :ESD4
if /i %_end% GTR %images% echo.&echo Range End is higher than available indexes&echo.&PAUSE&goto :ESD4
if /i %_start% EQU %_end% echo.&echo Range Start and End are equal. Use option 3 of main menu to export single index&echo.&PAUSE&goto :ESDMENU
cls
IF EXIST "%CD%\install.wim" (
ECHO ===============================================================================
ECHO. An install.wim file is already present in the current folder.
ECHO ===============================================================================
ECHO.
echo Press any key to exit.
pause >nul
GOTO :QUIT
)
ECHO ===============================================================================
Echo Exporting ESD Index %_start% to a new install.wim file...
ECHO ===============================================================================
mkdir temp
dism /Quiet /Capture-Image /ImageFile:install.wim /CaptureDir:.\temp /Name:container /Compress:max /CheckIntegrity
rmdir /s /q temp
dism /Export-Image /SourceImageFile:"%WIMFILE%" /SourceIndex:%_start% /DestinationImageFile:install.wim /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
dism /Quiet /Delete-Image /ImageFile:install.wim /Index:1 /CheckIntegrity
set /a _start+=1
for /L %%i in (%_start%, 1, %_end%) do (
ECHO.
ECHO ===============================================================================
Echo Exporting ESD Index %%i to install.wim file...
ECHO ===============================================================================
dism /Export-Image /SourceImageFile:"%WIMFILE%" /SourceIndex:%%i /DestinationImageFile:install.wim /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
)
echo.
echo Done.
echo.
echo Press any key to exit.
pause >nul
GOTO :QUIT
:WIMMENU
cls
ECHO ===============================================================================
ECHO. Detected WIM file contains %images% indexes:
ECHO.
for /L %%i in (1, 1, %images%) do (
ECHO. %%i. !name%%i!
)
ECHO.
ECHO ===============================================================================
ECHO. Options:
ECHO ===============================================================================
ECHO. 1 - Export 1st index
ECHO. 2 - Export all indexes
ECHO. 3 - Export selected single index
ECHO. 4 - Export selected range of indexes
ECHO ===============================================================================
ECHO. Press 'Q' to Quit
ECHO ===============================================================================
choice /c 1234q /n /m "Choose a menu option, or Q to quit: "
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP%==1 GOTO :WIM1
IF %ERRORTEMP%==2 GOTO :WIM2
IF %ERRORTEMP%==3 GOTO :WIM3
IF %ERRORTEMP%==4 GOTO :WIM4
IF %ERRORTEMP%==5 GOTO :QUIT
GOTO :MAINMENU
:WIM1
cls
IF EXIST "%CD%\install.esd" (
ECHO ===============================================================================
ECHO. An install.esd file is already present in the current folder.
ECHO ===============================================================================
ECHO.
echo Press any key to exit.
pause >nul
GOTO :QUIT
)
ECHO ===============================================================================
Echo Exporting WIM Index 1 to a new install.esd file...
ECHO ===============================================================================
echo.
echo *** This will require some time, high CPU and Disk usage, please be patient ***
echo.
dism /export-image /sourceimagefile:"%WIMFILE%" /Sourceindex:1 /destinationimagefile:install.esd /compress:recovery /checkintegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
echo.
echo Done.
echo.
echo Press any key to exit.
pause >nul
GOTO :QUIT
:WIM2
cls
IF EXIST "%CD%\install.esd" (
ECHO ===============================================================================
ECHO. An install.esd file is already present in the current folder.
ECHO ===============================================================================
ECHO.
echo Press any key to exit.
pause >nul
GOTO :QUIT
)
ECHO ===============================================================================
Echo Exporting WIM Index 1 to a new install.esd file...
ECHO ===============================================================================
echo.
echo *** This will require some time, high CPU and Disk usage, please be patient ***
echo.
dism /Export-Image /SourceImageFile:"%WIMFILE%" /Sourceindex:1 /DestinationImageFile:install.esd /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
if "%images%"=="1" (
echo.
echo Done.
echo.
echo Press any key to exit.
pause >nul
GOTO :QUIT
)
for /L %%i in (2, 1, %images%) do (
ECHO.
ECHO ===============================================================================
Echo Exporting WIM Index %%i to install.esd file...
ECHO ===============================================================================
dism /Export-Image /SourceImageFile:"%WIMFILE%" /SourceIndex:%%i /DestinationImageFile:install.esd /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
)
echo.
echo Done.
echo.
echo Press any key to exit.
pause >nul
GOTO :QUIT
:WIM3
cls
set _index=
ECHO ===============================================================================
ECHO. Detected WIM file contains %images% indexes:
ECHO.
for /L %%i in (1, 1, %images%) do (
ECHO. %%i. !name%%i!
)
ECHO.
ECHO ===============================================================================
ECHO. Enter desired index number to export
ECHO ===============================================================================
ECHO. Enter zero '0' to go back to Main Menu
ECHO ===============================================================================
set /p _index= ^>
if /i "%_index%"=="0" goto :WIMMENU
if [%_index%]==[] goto :WIM3
if /i %_index% GTR %images% echo.&echo Selected number is higher than available indexes&echo.&PAUSE&goto :WIM3
cls
IF EXIST "%CD%\install.esd" (
ECHO ===============================================================================
ECHO. An install.esd file is already present in the current folder.
ECHO ===============================================================================
ECHO.
echo Press any key to exit.
pause >nul
GOTO :QUIT
)
ECHO ===============================================================================
Echo Exporting WIM Index %_index% to a new install.esd file...
ECHO ===============================================================================
echo.
echo *** This will require some time, high CPU and Disk usage, please be patient ***
echo.
dism /Export-Image /SourceImageFile:"%WIMFILE%" /SourceIndex:%_index% /DestinationImageFile:install.esd /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
echo.
echo Done.
echo.
echo Press any key to exit.
pause >nul
GOTO :QUIT
:WIM4
cls
set _range=
set _start=
set _end=
ECHO ===============================================================================
ECHO. Detected WIM file contains %images% indexes:
ECHO.
for /L %%i in (1, 1, %images%) do (
ECHO. %%i. !name%%i!
)
ECHO.
ECHO ===============================================================================
ECHO. Enter desired Range of indexes to export: Start-End
ECHO. Example: 2-4 or 1-3 or 3-4
ECHO ===============================================================================
ECHO. Enter zero '0' to go back to Main Menu
ECHO ===============================================================================
set /p _range= ^>
if /i "%_range%"=="0" goto :WIMMENU
if [%_range%]==[] goto :WIM4
for /f "tokens=1 delims=-" %%i in ('echo %_range%') do set _start=%%i
for /f "tokens=2 delims=-" %%i in ('echo %_range%') do set _end=%%i
if /i %_start% GTR %images% echo.&echo Range Start is higher than available indexes&echo.&PAUSE&goto :WIM4
if /i %_end% GTR %images% echo.&echo Range End is higher than available indexes&echo.&PAUSE&goto :WIM4
if /i %_start% EQU %_end% echo.&echo Range Start and End are equal. Use option 3 of main menu to export single index&echo.&PAUSE&goto :WIMMENU
cls
IF EXIST "%CD%\install.esd" (
ECHO ===============================================================================
ECHO. An install.esd file is already present in the current folder.
ECHO ===============================================================================
ECHO.
echo Press any key to exit.
pause >nul
GOTO :QUIT
)
ECHO ===============================================================================
Echo Exporting WIM Index %_start% to a new install.esd file...
ECHO ===============================================================================
echo.
echo *** This will require some time, high CPU and Disk usage, please be patient ***
echo.
dism /Export-Image /SourceImageFile:"%WIMFILE%" /SourceIndex:%_start% /DestinationImageFile:install.esd /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
set /a _start+=1
for /L %%i in (%_start%, 1, %_end%) do (
ECHO.
ECHO ===============================================================================
Echo Exporting WIM Index %%i to install.esd file...
ECHO ===============================================================================
dism /Export-Image /SourceImageFile:"%WIMFILE%" /SourceIndex:%%i /DestinationImageFile:install.esd /compress:recovery /CheckIntegrity
SET ERRORTEMP=%ERRORLEVEL%
IF %ERRORTEMP% NEQ 0 (ECHO.&Echo Errors were reported during dism export.&PAUSE&GOTO :QUIT)
)
echo.
echo Done.
echo.
echo Press any key to exit.
pause >nul
GOTO :QUIT
:QUIT

View File

@@ -0,0 +1,267 @@
param([switch]$Elevated)
function Check-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
if ((Check-Admin) -eq $false)  {
if ($elevated)
{
# could not elevate, quit
}
 
else {
 
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
}
exit
}
function Write-ProgressHelper {
param (
[int]$StepNumber,
[string]$Message
)
Write-Progress -Activity 'PSC Update Readiness 2019' -Status $Message -PercentComplete (($StepNumber / $steps) * 100)
}
$script:steps = ([System.Management.Automation.PsParser]::Tokenize((gc "$PSScriptRoot\$($MyInvocation.MyCommand.Name)"), [ref]$null) | where { $_.Type -eq 'Command' -and $_.Content -eq 'Write-ProgressHelper' }).Count
$stepCounter = 0
Write-ProgressHelper -Message 'Checking For Previous Run' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 2.5
$ErrorActionPreference="SilentlyContinue"
$maxRepeat = 10
$Organisation = "PSC"
$ThisPC = ($env:COMPUTERNAME + $env:username)
$freespaceError = ("$env:COMPUTERNAME only has $spacegb GB Free and cannot continue 1903 install")
$TeamViewerFileName = "c:\teamviewer_install\TeamviewerHost.msi"
$InTuneLog = "c:\InTune_Log\$env:COMPUTERNAME.log"
$InTuneFolder = "c:\InTune_Log\*.*"
$InTune_Folder = "c:\InTune_Log\"
$ts = New-TimeSpan -Hours 2
function not-exist { -not (Test-Path -Path $TeamViewerFileName) }
#Set-Alias !exist not-exist -Option "Constant, AllScope"
#Set-Alias exist Test-Path -Option "Constant, AllScope"
Add-Type -AssemblyName System.Windows.Forms | Out-Null
Stop-Transcript | out-null
$ErrorActionPreference = "Continue"
If (-not(Test-Path -Path $InTune_Folder)) {
mkdir $InTune_Folder }
filter timestamp {"$(Get-Date -Format G): $_"}
if (Test-Path -Path $InTuneLog) {
Remove-Item $InTuneLog -ErrorAction SilentlyContinue
Remove-Item $InTune_Folder\$env:COMPUTERNAME.zip -Force -ErrorAction SilentlyContinue
Remove-Item c:\InTune_Log\"$env:COMPUTERNAME"_Transcript.log -ErrorAction SilentlyContinue
Remove-Item c:\InTune_Log\"$env:COMPUTERNAME".csv -ErrorAction SilentlyContinue
Remove-Item c:\InTune_Log\$env:Computername-Bitlocker-Recovery-key.txt -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1.5}
Else
{
# Move On
}
Start-Transcript -path c:\InTune_Log\"$env:COMPUTERNAME"_Transcript.log
Write-ProgressHelper -Message 'Checking For Teamviewer' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 2.5
############################################################################
# Teamviewer Start
############################################################################
#Get Teamviewer
if (-not (Test-Path -Path $TeamViewerFileName)) {
mkdir c:\teamviewer_install
$url = "https://onedrive.live.com/download?cid=77FB0E4F642F10B7&resid=77FB0E4F642F10B7%21273176&authkey=AOouFE3GDGRSHIc"
$output = "c:\teamviewer_install\TeamviewerHost.msi"
$start_time = Get-Date
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($url, $output)
Write-Host "Temaviewer Downloaded"
msiexec.exe /i "c:\teamviewer_install\TeamviewerHost.msi" /qn CUSTOMCONFIGID=6988pev APITOKEN=6581446-B1aEz7nIk9k92p4G7C1R ASSIGNMENTOPTIONS="--grant-easy-access"
Write-Host "Teamviewer Installed"
}
Else
{
Write-Host "TeamViewer Already Installed"
}
#############################################################################
# Teamviewer End
#############################################################################
Write-ProgressHelper -Message 'Checking Your PC Integrity - Integrity Is Important You Know' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 5
##############################################################################
# Computer Sanity Check End
##############################################################################
# Power Connect Check
#Function Check-BatteryState {
#param($Laptop=$env:computername)
#$Bstatus = ((Get-WmiObject -Class Win32_Battery).BatteryStatus)
#}
$Bstatus = ((Get-WmiObject -Class Win32_Battery).BatteryStatus)
if($Bstatus) {
switch ($Bstatus)
{
1 { "Battery is discharging" }
2 { "The system has access to AC so no battery is being discharged. However, the battery is not necessarily charging." }
3 { "Fully Charged" }
4 { "Low" }
5 { "Critical" }
6 { "Charging" }
7 { "Charging and High" }
8 { "Charging and Low" }
9 { "Charging and Critical " }
10 { "Unknown State" }
11 { "Partially Charged" }
}
}
If ($BStatus -eq 2) {
# Move On
}
Else {
[System.Windows.Forms.MessageBox]::Show("You Need To Be Connected To The Power Adapter! Please re run from Software Center when power is avalable. Exiting...", $Organisation,
[System.Windows.Forms.MessageBoxButtons]::OK,
[System.Windows.Forms.MessageBoxIcon]::ERROR)
}
# Power Connect Check End
#----------------------------------------------------------------------------
Write-ProgressHelper -Message 'Checking Your Free Drive Space - You Should Be Saving Everything To The Cloud Anyway' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 5
#----------------------------------------------------------------------------
# Free Space Check Start
$disk = Get-WMIObject Win32_Logicaldisk -filter "deviceid='$((Get-WMIObject Win32_OperatingSystem -computername $env:COMPUTERNAME).systemdrive)'" -ComputerName $env:COMPUTERNAME
$freespace = ($disk.FreeSpace)
$spacegb = [math]::Round($disk.Freespace/1GB,2)
# Free Space Check End
#----------------------------------------------------------------------------
Write-ProgressHelper -Message 'Checking Your PC Is Secure - Safety First!' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 5
#----------------------------------------------------------------------------
# Bitlocker Status
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
$blockerstatus = (Get-BitlockerVolume -MountPoint "C:")
#----------------------------------------------------------------------------
Write-ProgressHelper -Message 'Checking For PSC Admin' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 5
#----------------------------------------------------------------------------
# PSC Admin User Check Start
$UserPassword = ConvertTo-SecureString "Restore99!" -AsPlainText -Force
$psclocaladmin = $null
If ($psclocaladmin = Get-LocalUser pscadmin)
{
Add-LocalGroupMember -Group "Administrators" -Member "pscadmin"
Enable-LocalUser -Name "pscadmin"
}
Else
{
# If (!$psclocaladmin)
New-LocalUser "pscadmin" -Password $UserPassword -FullName "PSC Admin" -Description "PSC Admin Account" -AccountNeverExpires -PasswordNeverExpires
Add-LocalGroupMember -Group "Administrators" -Member "pscadmin"
Enable-LocalUser -Name "pscadmin"
}
# PSC Admin User Check End
#----------------------------------------------------------------------------
Write-ProgressHelper -Message 'Creating Restore Point - We Like To Play It Safe!' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 10
#----------------------------------------------------------------------------
# System Restore Check Start
Enable-ComputerRestore -Drive "C:\"
Checkpoint-Computer -Description "New Intune Setup 2019" -RestorePointType MODIFY_SETTINGS
# System Restore Check End
#----------------------------------------------------------------------------
##############################################################################
# Computer Sanity Check End
##############################################################################
Write-ProgressHelper -Message 'Checking For Errors - Its Windows 10, As If There Would Be Errors!?' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 5
# Errors
If($freespace -lt 32212254720 ) {
$freespaceError | Format-Table | Out-File -append "c:\InTune_Log\$env:COMPUTERNAME.log" | Write-Output
}
else {
# No Error To See Here, Keep Moving!
}
If ($blockerstatus.protectionstatus -ne "On") {
Enable-BitLocker -MountPoint C: -UsedSpaceOnly -SkipHardwareTest -RecoveryKeyPath "c:\InTune_Log\" -RecoveryKeyProtector
manage-bde -protectors -get c: >> c:\InTune_Log\$env:Computername-Bitlocker-Recovery-key.txt
("BitLocker Was Off") | Format-Table | Out-File -append "c:\InTune_Log\$env:COMPUTERNAME.log" | Write-Output
}
Else
{
manage-bde -protectors -get c: >> c:\InTune_Log\$env:Computername-Bitlocker-Recovery-key.txt
}
Start-Sleep -Seconds 1.5
if ($BStatus -ne 2)
{
("$env:username Did Not Plug In To Mains") | Format-Table | Out-File -append "c:\InTune_Log\$env:COMPUTERNAME.log" | Write-Output
}
# AutoPilot Hardware Hash
Install-Script -Name Get-WindowsAutoPilotInfo -Force
Start-Sleep -Seconds 3
Get-WindowsAutoPilotInfo.ps1 -append -OutputFile "c:\InTune_Log\$env:COMPUTERNAME.csv"
Start-Sleep -Seconds 2.5
Stop-Transcript
# Fail
$LogsExist = (Test-Path $InTuneLog)
Write-ProgressHelper -Message 'Sending Data To PSC IT' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 4
if (Test-Path $InTuneLog)
{
$psclocaladmin | Format-Table | Out-File -append "c:\InTune_Log\$env:COMPUTERNAME.log" | Write-Output
("BitLocker Was Off, It has now been switched on by InTune Script. Please try again in an hour") | Format-Table | Out-File -append "c:\InTune_Log\$env:COMPUTERNAME.log" | Write-Output
Compress-Archive -Path $InTuneFolder -DestinationPath $InTune_Folder\$env:COMPUTERNAME.zip
Start-Sleep -Seconds 5
Send-MailMessage -from "$env:username<kurt.frohloff@pscconsulting.com>" -to "IT<it@pscconsulting.com>" -Subject "AAD Intune Upgrade Report Fail $env:computername" -Body "$env:COMPUTERNAME InTune Logs" -Attachments "$InTune_Folder\$env:COMPUTERNAME.zip" -SmtpServer "pscconsulting-com.mail.protection.outlook.com"
curl "https://onedrive.live.com/download?cid=77FB0E4F642F10B7&resid=77FB0E4F642F10B7%21273301&authkey=AEReiJb0-g1gGqc" -o "$InTune_Folder\sendfile.ps1"
Invoke-Expression (($InTune_Folder)+"\sendfile.ps1")
Remove-Item $InTune_Folder\sendfile.ps1 -Force -ErrorAction SilentlyContinue
[System.Windows.Forms.MessageBox]::Show("The PSC IT Update Readiness Tool Has Completed Its Task. All Details Have Been Sent To PSC IT.", $Organisation,
[System.Windows.Forms.MessageBoxButtons]::OK,
[System.Windows.Forms.MessageBoxIcon]::INFORMATION)
}
Else
{
("BitLocker Was Already On") | Format-Table | Out-File -append "c:\InTune_Log\$env:COMPUTERNAME.log" | Write-Output
$psclocaladmin | Format-Table | Out-File -append "c:\InTune_Log\$env:COMPUTERNAME.log" | Write-Output
("$env:COMPUTERNAME has $spacegb GB Free") | Format-Table | Out-File -append "c:\InTune_Log\$env:COMPUTERNAME.log" | Write-Output
Compress-Archive -Path $InTuneFolder -DestinationPath $InTune_Folder\$env:COMPUTERNAME.zip
Start-Sleep -Seconds 5
Send-MailMessage -from "$env:username<kurt.frohloff@pscconsulting.com>" -to "IT<it@pscconsulting.com>" -Subject "AAD Intune Upgrade Report Success $env:computername" -Body "$env:COMPUTERNAME InTune Logs" -Attachments "$InTune_Folder\$env:COMPUTERNAME.zip" -SmtpServer "pscconsulting-com.mail.protection.outlook.com"
curl "https://onedrive.live.com/download?cid=77FB0E4F642F10B7&resid=77FB0E4F642F10B7%21273301&authkey=AEReiJb0-g1gGqc" -o "$InTune_Folder\sendfile.ps1"
Invoke-Expression (($InTune_Folder)+"\sendfile.ps1")
Remove-Item $InTune_Folder\sendfile.ps1 -Force -ErrorAction SilentlyContinue
[System.Windows.Forms.MessageBox]::Show("The PSC IT Update Readiness Tool Has Completed Its Task. All Details Have Been Sent To PSC IT.", $Organisation,
[System.Windows.Forms.MessageBoxButtons]::OK,
[System.Windows.Forms.MessageBoxIcon]::INFORMATION)
}
Write-ProgressHelper -Message 'Checkup Complete - Thanks For Playing' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 3

View File

@@ -0,0 +1,172 @@
$MainMenu = {
Write-Host " ************************************************"
Write-Host " * Assign Teams Calling Number to AU or NZ User *"
Write-Host " ************************************************"
Write-Host
Write-Host " 1.) Connect To Teams Online"
Write-Host " 2.) Export Currently Assigned Numbers"
Write-Host " 3.) Assign AU Number"
Write-Host " 4.) Assign NZ Number"
Write-Host " 5.) Quit"
Write-Host
Write-Host " Select an option and press Enter: " -nonewline
}
cls
$psc = '@pscconsulting.com'
Do {
cls
Invoke-Command $MainMenu
$Select = Read-Host
Switch ($Select)
{
1 {
Write-Host "Checking For Teams Module"
if (Get-Module -ListAvailable -Name MicrosoftTeams) {
Write-Host "MicrosoftTeams Module Already Installed - Importing"
Import-Module MicrosoftTeams
Connect-MicrosoftTeams
}
else {
Write-Host "MicrosoftTeams Module does not exist - Installing"
Install-Module MicrosoftTeams -Force -AllowClobber
Import-Module MicrosoftTeams
Connect-MicrosoftTeams
}
}
2 {
function Write-ProgressHelper {
param (
[int]$StepNumber,
[string]$Message
)
Write-Progress -Activity 'Export All Current DDI Numbers That Are In Use to C:\Temp\' -Status $Message -PercentComplete (($StepNumber / $steps) * 100)
}
$script:steps = ([System.Management.Automation.PsParser]::Tokenize((gc "$PSScriptRoot\$($MyInvocation.MyCommand.Name)"), [ref]$null) | where { $_.Type -eq 'Command' -and $_.Content -eq 'Write-ProgressHelper' }).Count
$stepCounter = 0
Write-ProgressHelper -Message 'Checking For Temp Direcory' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 2.5
$ErrorActionPreference="SilentlyContinue"
#Check If Directory Exists #############
$DirectoryToCreate = "C:\Temp\"
if (-not (Test-Path -LiteralPath $DirectoryToCreate)) {
Write-Host "Directory does not exist - creating..."
New-Item -Path $DirectoryToCreate -ItemType Directory -ErrorAction Stop | Out-Null #-Force
Write-Host "Successfully created directory '$DirectoryToCreate'."
}
else {
Write-Host "Directory already exists"
}
Write-ProgressHelper -Message 'Checking For Temp Direcory' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 2.5
#Connect to Teams
Write-Host "Connecting to MS Teams"
Connect-MicrosoftTeams
Write-ProgressHelper -Message 'Getting Used Numbers and Exporting to CSV' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 2.5
#Settings ##############################
#. "_Settings.ps1" | Out-Null
$FileName = "TeamsAssignedNumbers_" + (Get-Date -Format s).replace(":","-") +".csv"
$FilePath = "C:\Temp\$FileName"
$OutputType = "CSV" #OPTIONS: CSV - Outputs CSV to specified FilePath, CONSOLE - Outputs to console
##############################
$Regex1 = '^(?:tel:)?(?:\+)?(\d+)(?:;ext=(\d+))?(?:;([\w-]+))?$'
$Array1 = @()
#Get Users with LineURI
$UsersLineURI = Get-CsOnlineUser -Filter {LineURI -ne $Null}
if($UsersLineURI -ne $null)
{
foreach($item in $UsersLineURI)
{
$Matches = @()
$Item.LineURI -match $Regex1 | out-null
$myObject1 = New-Object System.Object
$myObject1 | Add-Member -type NoteProperty -name "LineURI" -Value $Item.LineURI
$myObject1 | Add-Member -type NoteProperty -name "DDI" -Value $Matches[1]
# $myObject1 | Add-Member -type NoteProperty -name "Ext" -Value $Matches[2]
$myObject1 | Add-Member -type NoteProperty -name "DisplayName" -Value $Item.DisplayName
# $myObject1 | Add-Member -type NoteProperty -name "FirstName" -Value $Item.FirstName
# $myObject1 | Add-Member -type NoteProperty -name "LastName" -Value $Item.LastName
$myObject1 | Add-Member -type NoteProperty -name "Type" -Value "User"
$Array1 += $myObject1
}
}
#Get meeting room numbers
$MeetingRoomLineURI = Get-CsMeetingRoom -Filter {LineURI -ne $Null}
if($MeetingRoomLineURI -ne $null)
{
Write-Verbose "Processing Meeting Room Numbers"
foreach($Item in $MeetingRoomLineURI)
{
$Matches = @()
$Item.LineURI -match $Regex1 | out-null
$myObject1 = New-Object System.Object
$myObject1 | Add-Member -type NoteProperty -name "LineURI" -Value $Item.LineURI
$myObject1 | Add-Member -type NoteProperty -name "DDI" -Value $Matches[1]
$myObject1 | Add-Member -type NoteProperty -name "Ext" -Value $Matches[2]
$myObject1 | Add-Member -type NoteProperty -name "DisplayName" -Value $Item.DisplayName
$myObject1 | Add-Member -type NoteProperty -name "Type" -Value "MeetingRoom"
$Array1 += $myObject1
}
}
#Get online resource accounts
$OnlineApplicationInstanceLineURI = Get-CsOnlineApplicationInstance | where {$_.PhoneNumber -ne $Null}
if($OnlineApplicationInstanceLineURI -ne $null)
{
Write-Verbose "Processing Online Application Instances (Resource Accounts) Numbers"
foreach($Item in $OnlineApplicationInstanceLineURI)
{
$Matches = @()
$Item.PhoneNumber -match $Regex1 | out-null
$myObject1 = New-Object System.Object
$myObject1 | Add-Member -type NoteProperty -name "LineURI" -Value $Item.PhoneNumber
$myObject1 | Add-Member -type NoteProperty -name "DDI" -Value $Matches[1]
$myObject1 | Add-Member -type NoteProperty -name "Ext" -Value $Matches[2]
$myObject1 | Add-Member -type NoteProperty -name "DisplayName" -Value $Item.DisplayName
$myObject1 | Add-Member -type NoteProperty -name "Type" -Value $(if ($item.ApplicationId -eq "ce933385-9390-45d1-9512-c8d228074e07") {"Auto Attendant Resource Account"} elseif ($item.ApplicationId -eq "11cd3e2e-fccb-42ad-ad00-878b93575e07") {"Call Queue Resource Account"} else {"Unknown Resource Account"})
$Array1 += $myObject1
}
}
if($OutputType -eq "CSV")
{
$Array1 | export-csv $FilePath -NoTypeInformation
Write-Host "ALL DONE!! Your file has been saved to $FilePath."
}
elseif($OutputType -eq "CONSOLE")
{
$Array1 | FT -AutoSize -Property LineURI,DDI,Ext,DisplayName,Type
Write-Host "ALL DONE!!"
}
else
{
$Array1 | FT -AutoSize -Property LineURI,DDI,Ext,DisplayName,Type
Write-Host "WARNING: Valid output type not set, defaulted to console."
Read-Host -Prompt "Press any key to continue..."
}
}
3 {
$firstname = Read-Host -Prompt "Enter User First Name"
$lastname = Read-Host -Prompt "Enter User Last Name"
$AUPhone = Read-Host -Prompt "Enter User Phone Number, Including Single Digit Area Code Only. Country Code Not Required"
$Name = "$firstname.$lastname@pscconsulting.com"
Set-CsPhoneNumberAssignment -Identity $Name -PhoneNumber +61$AUPhone -PhoneNumberType DirectRouting
Set-CsPhoneNumberAssignment -Identity $Name -EnterpriseVoiceEnabled $true
Grant-CsOnlineVoiceRoutingPolicy -Identity $Name -PolicyName MacTelAustralia
Read-Host -Prompt "Press any key to continue..."
}
4 {
$firstname = Read-Host -Prompt "Enter User First Name"
$lastname = Read-Host -Prompt "Enter User Last Name"
$NZPhone = Read-Host -Prompt "Enter User Phone Number, Including Single Digit Area Code Only. Country Code Not Required"
$Name = "$firstname.$lastname@pscconsulting.com"
Set-CsPhoneNumberAssignment -Identity $Name -PhoneNumber +64$NZPhone -PhoneNumberType DirectRouting
Set-CsPhoneNumberAssignment -Identity $Name -EnterpriseVoiceEnabled $true
Grant-CsOnlineVoiceRoutingPolicy -Identity $Name -PolicyName "Vocus NZ International"
Read-Host -Prompt "Press any key to continue..."
}
}
}
While ($Select -ne 5)

View File

@@ -0,0 +1,28 @@
@echo off
:: BatchGotAdmin
::-------------------------------------
REM --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
echo Requesting administrative privileges...
goto UACPrompt
) else ( goto gotAdmin )
:UACPrompt
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
set params = %*:"="
echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs"
exit /B
:gotAdmin
pushd "%CD%"
CD /D "%~dp0"
::--------------------------------------
powershell -command "& {Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force}"
powershell ./Intune.ps1

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
#Setting registry key to block AAD Registration to 3rd party tenants.
$RegistryLocation = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WorkplaceJoin\"
$keyname = "BlockAADWorkplaceJoin"
#Test if path exists and create if missing
if (!(Test-Path -Path $RegistryLocation)){
Write-Output "Registry location missing. Creating"
New-Item $RegistryLocation | Out-Null
}
#Force create key with value 1
New-ItemProperty -Path $RegistryLocation -Name $keyname -PropertyType DWord -Value 1 -Force | Out-Null
Write-Output "Registry key set"

View File

@@ -0,0 +1,54 @@
<#
.Synopsis Detects, downloads, installs and configures the latest version of TeamViewer.
.Notes
Requires TeamViewer 14.
TeamViewer Installation Documentation
https://community.teamviewer.com/t5/Knowledge-Base/Mass-deployment-improvements/ta-p/39639
#>
$ConfigurationID = "64uyck9"
$ApiToken = "6615740-y9LI6bdNq5QtaDtiGVTN"
$ComputerName = $ENV:COMPUTERNAME
if (Test-Path 'C:\Program Files (x86)\TeamViewer\TeamViewer.exe') {
Write-Host 'Team Viewer already installed.'
return
}
Write-Host 'Installing TeamViewer.'
Write-Host 'Downloading TeamViewer Host Setup.'
$SetupFilePath = Join-Path $ENV:TEMP "TeamViewer_Host_Setup-idc$($ConfigurationID).exe"
$response = Invoke-RestMethod "https://get.teamviewer.com/$ConfigurationID"
$json = '{}'
if ($response -match 'configId = "(?<ConfigId>[^"]+).*\n.*version = "(?<Version>[^"]+).*\n.*isCustomModule = (?<IsCustomModule>[^"]+);.*\n.*subdomain = "(?<Subdomain>[^"]+)(?<ConnectionId>)' ) {
$Matches.Remove(0)
$Matches['IsCustomModule'] = if ($Matches['IsCustomModule'] -eq 'true') { $true } else { $false }
$json = [PsCustomObject]$Matches | ConvertTo-Json
}
else {
throw 'Expected JSON values not found in initial HTML page'
}
$DownloadUri = Invoke-RestMethod -Uri 'https://get.teamviewer.com/api/CustomDesign' -Method Post -Body $json -ContentType 'application/json'
Invoke-WebRequest -Uri $DownloadUri -OutFile $SetupFilePath
if (-not (Test-Path $SetupFilePath)) {
throw 'TeamViewer_Setup.exe failed to download.'
}
Write-Host 'Installing.'
& $SetupFilePath /S | Write-Output
Write-Debug "$SetupFilePath LastExitCode = $LASTEXITCODE"
Write-Host 'Configuring'
& "C:\Program Files (x86)\TeamViewer\TeamViewer.exe" assign --api-token $ApiToken --grant-easy-access --reassign --alias $ComputerName | Write-Output
Write-Debug "TeamViewer.exe assign LastExitCode = $LASTEXITCODE"
Write-Host 'Cleaning up.'
$SetupTempFolder = Join-Path $ENV:TEMP 'TeamViewer'
$SetupFilePath, $SetupTempFolder | Remove-Item -Recurse
Write-Host 'Complete.'

View File

@@ -0,0 +1,51 @@
param([switch]$Elevated)
function Check-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
if ((Check-Admin) -eq $false)  {
if ($elevated)
{
# could not elevate, quit
}
 
else {
 
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
}
exit
}
$TempInstallDir = "c:\teamviewer_install\"
if (Test-Path $TempInstallDir) {
Remove-Item $TempInstallDir -Recurse -Force
}
else
{
Write-Host "Install Start"
}
$TeamViewerFileName = "C:\Program Files (x86)\TeamViewer\TeamViewer.exe"
$TeamViewer64FileName = "C:\Program Files\TeamViewer\TeamViewer.exe"
function not-exist { -not (Test-Path -Path $TeamViewer64FileName) }
function not-exist { -not (Test-Path -Path $TeamViewerFileName) }
if (-not (Test-Path -Path $TeamViewerFileName)) {}
if (-not (Test-Path -Path $TeamViewer64FileName)) {
mkdir c:\teamviewer_install
$url = "https://download.teamviewer.com/download/version_15x/TeamViewer_MSI32.zip"
$output = "c:\teamviewer_install\TeamviewerHost.zip"
$tvdir = "c:\teamviewer_install"
$start_time = Get-Date
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($url, $output)
Write-Host "Teamviewer Downloaded"
sleep 3
Expand-Archive -LiteralPath $output -DestinationPath $tvdir -Force
msiexec.exe /i "c:\teamviewer_install\Host\Teamviewer_Host.msi" /qn CUSTOMCONFIGID=6988pev APITOKEN=6581446-B1aEz7nIk9k92p4G7C1R ASSIGNMENTOPTIONS="--grant-easy-access"
Write-Host "Teamviewer Installed"
}
Else
{
Write-Host "TeamViewer Already Installed"
}

View File

@@ -0,0 +1,40 @@
function Get-ServiceId {
#Set the registry path containing the service ID
$RegistryPath = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OnlineManagement"
try {
#Get all the names of the items in the registry location
$RegistryItems = (Get-ChildItem -Path Registry::$RegistryPath -ErrorAction Stop).Name
#Loop through all the results
foreach ($RegistryItem in $RegistryItems) {
#Find the result that starts with the registry location followed by the first sign of a GUID
if ($RegistryItem.StartsWith("$RegistryPath\{")) {
#Replace the registry location with nothing to get the GUID
$ServiceId = $RegistryItem.Replace("$RegistryPath\","")
break
}
}
return $ServiceId
}
catch {
Write-Output "The Microsoft Intune client is not installed"
}
}
function Start-Uninstall {
param (
[parameter(Mandatory=$true)]$ServiceId
)
try {
#Set the ProvisioningUtil location and parameters
$ProvisioningUtilPath = "C:\Program Files\Microsoft\OnlineManagement\Common"
$ProvisioningUtilExecutable = "ProvisioningUtil.exe"
$ProvisioningUtilArguments = "/UninstallClient /ServiceId $ServiceId /TaskName 'tempTask' /SubEventId 16"
#Trigger the uninstall of the Microsoft Intune client
Start-Process -FilePath "$($ProvisioningUtilPath)\$($ProvisioningUtilExecutable)" -ArgumentList $ProvisioningUtilArguments -Wait -PassThru
}
catch {
Write-Output "Failed to trigger the uninstall of the Microsoft Intune client"
}
}
Start-Uninstall (Get-ServiceId)

View File

@@ -0,0 +1,545 @@
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Full C: drive space recovery scanner with user confirmation before cleanup.
.DESCRIPTION
Scans for recoverable disk space across common Windows Server bloat sources.
Reports findings with sizes, then prompts for confirmation before touching anything.
.NOTES
Supports: Windows Server 2016, 2019, 2022, 2025
Run as: Administrator
Author: SBCIT
#>
Set-StrictMode -Version Latest
$ErrorActionPreference = 'SilentlyContinue'
# ─────────────────────────────────────────────
# HELPERS
# ─────────────────────────────────────────────
function Format-Size {
param([long]$Bytes)
if ($Bytes -ge 1GB) { return "{0:N2} GB" -f ($Bytes / 1GB) }
if ($Bytes -ge 1MB) { return "{0:N2} MB" -f ($Bytes / 1MB) }
if ($Bytes -ge 1KB) { return "{0:N2} KB" -f ($Bytes / 1KB) }
return "$Bytes B"
}
function Get-FolderSize {
param([string]$Path)
if (-not (Test-Path $Path)) { return 0 }
try {
(Get-ChildItem -Path $Path -Recurse -Force -File -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum).Sum
} catch { 0 }
}
function Get-RecycleBinSize {
$total = 0
try {
$shell = New-Object -ComObject Shell.Application
$recycle = $shell.Namespace(0xA)
foreach ($item in $recycle.Items()) {
try { $total += $item.Size } catch {}
}
} catch {}
return $total
}
function Write-Header {
param([string]$Text)
Write-Host "`n [$Text]" -ForegroundColor Cyan
Write-Host " $('─' * 60)" -ForegroundColor DarkGray
}
function Write-FindingLine {
param([string]$Label, [long]$Bytes, [string]$Note = '')
$size = Format-Size $Bytes
$color = if ($Bytes -gt 500MB) { 'Yellow' } elseif ($Bytes -gt 50MB) { 'White' } else { 'DarkGray' }
$noteStr = if ($Note) { " ($Note)" } else { '' }
Write-Host (" {0,-48} {1,10}{2}" -f $Label, $size, $noteStr) -ForegroundColor $color
}
# ─────────────────────────────────────────────
# BANNER
# ─────────────────────────────────────────────
Clear-Host
Write-Host ""
Write-Host " ╔══════════════════════════════════════════════════════════╗" -ForegroundColor DarkCyan
Write-Host " ║ SBCIT // C: DRIVE CLEANUP SCANNER ║" -ForegroundColor DarkCyan
Write-Host " ║ Windows Server 2016 → Current ║" -ForegroundColor DarkCyan
Write-Host " ╚══════════════════════════════════════════════════════════╝" -ForegroundColor DarkCyan
Write-Host ""
Write-Host " Host : $($env:COMPUTERNAME)" -ForegroundColor Gray
Write-Host " User : $($env:USERNAME)" -ForegroundColor Gray
Write-Host " Date : $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Gray
Write-Host ""
# ─────────────────────────────────────────────
# PRE-SCAN: DRIVE STATE
# ─────────────────────────────────────────────
$drive = Get-PSDrive C
$freeGB = [math]::Round($drive.Free / 1GB, 2)
$totalGB = [math]::Round(($drive.Used + $drive.Free) / 1GB, 2)
$usedGB = [math]::Round($drive.Used / 1GB, 2)
$freePct = [math]::Round(($drive.Free / ($drive.Used + $drive.Free)) * 100, 1)
Write-Host " C: Drive Status" -ForegroundColor White
Write-Host " $('─' * 60)" -ForegroundColor DarkGray
Write-Host (" Total: {0} GB Used: {1} GB Free: {2} GB ({3}% free)" -f $totalGB, $usedGB, $freeGB, $freePct) -ForegroundColor $(if ($freePct -lt 15) { 'Red' } elseif ($freePct -lt 25) { 'Yellow' } else { 'Green' })
# ─────────────────────────────────────────────
# SCAN TARGETS — build a list of items
# ─────────────────────────────────────────────
Write-Host "`n Scanning... this may take a moment.`n" -ForegroundColor DarkYellow
$scanResults = [System.Collections.Generic.List[PSCustomObject]]::new()
function Add-Result {
param(
[string]$Category,
[string]$Label,
[string]$Path,
[long]$Size,
[string]$CleanupType, # Folder | RecycleBin | WindowsCleanMgr | EventLogs | TempFiles | IISLogs | WER | DeliveryOpt | MiniDumps | PrefetchCache
[string]$Note = ''
)
if ($Size -gt 0) {
$scanResults.Add([PSCustomObject]@{
Category = $Category
Label = $Label
Path = $Path
Size = $Size
CleanupType = $CleanupType
Note = $Note
Selected = $true
})
}
}
# ── TEMP FILES ──────────────────────────────
$winTemp = Get-FolderSize "C:\Windows\Temp"
$sysTemp = Get-FolderSize $env:TEMP
$userTemp = Get-FolderSize "C:\Users\$env:USERNAME\AppData\Local\Temp"
Add-Result "Temp Files" "Windows Temp (C:\Windows\Temp)" "C:\Windows\Temp" $winTemp "Folder"
Add-Result "Temp Files" "System Temp ($env:TEMP)" $env:TEMP $sysTemp "Folder"
Add-Result "Temp Files" "User Temp (AppData\Local\Temp)" "C:\Users\$env:USERNAME\AppData\Local\Temp" $userTemp "Folder"
# ── WINDOWS UPDATE / WINSXS ─────────────────
$softwaredist = Get-FolderSize "C:\Windows\SoftwareDistribution\Download"
$winsxsBackup = Get-FolderSize "C:\Windows\WinSxS\Backup"
Add-Result "Windows Update" "SoftwareDistribution\Download" "C:\Windows\SoftwareDistribution\Download" $softwaredist "Folder" "Cached WU downloads"
Add-Result "Windows Update" "WinSxS\Backup" "C:\Windows\WinSxS\Backup" $winsxsBackup "Folder" "Old component backups"
# ── CBS / COMPONENT LOGS ────────────────────
$cbsLogs = Get-FolderSize "C:\Windows\Logs\CBS"
Add-Result "System Logs" "CBS Logs (C:\Windows\Logs\CBS)" "C:\Windows\Logs\CBS" $cbsLogs "Folder"
# ── WINDOWS ERROR REPORTING ──────────────────
$werUser = Get-FolderSize "C:\ProgramData\Microsoft\Windows\WER\ReportQueue"
$werArch = Get-FolderSize "C:\ProgramData\Microsoft\Windows\WER\ReportArchive"
$werUser2 = Get-FolderSize "C:\Users\$env:USERNAME\AppData\Local\Microsoft\Windows\WER"
Add-Result "Error Reporting" "WER ReportQueue" "C:\ProgramData\Microsoft\Windows\WER\ReportQueue" $werUser "WER"
Add-Result "Error Reporting" "WER ReportArchive" "C:\ProgramData\Microsoft\Windows\WER\ReportArchive" $werArch "WER"
Add-Result "Error Reporting" "WER User Reports" "C:\Users\$env:USERNAME\AppData\Local\Microsoft\Windows\WER" $werUser2 "WER"
# ── MINIDUMPS ───────────────────────────────
$miniDump = Get-FolderSize "C:\Windows\Minidump"
$memDump = if (Test-Path "C:\Windows\MEMORY.DMP") { (Get-Item "C:\Windows\MEMORY.DMP").Length } else { 0 }
Add-Result "Crash Dumps" "Minidumps (C:\Windows\Minidump)" "C:\Windows\Minidump" $miniDump "MiniDumps"
Add-Result "Crash Dumps" "Full Memory Dump (MEMORY.DMP)" "C:\Windows\MEMORY.DMP" $memDump "Folder" "Single file"
# ── PREFETCH ────────────────────────────────
$prefetch = Get-FolderSize "C:\Windows\Prefetch"
Add-Result "Prefetch" "Prefetch Cache" "C:\Windows\Prefetch" $prefetch "PrefetchCache" "Server may have Prefetch disabled"
# ── DELIVERY OPTIMISATION ───────────────────
$delivOptFiles = Get-FolderSize "C:\Windows\SoftwareDistribution\DeliveryOptimization"
$delivOpt2 = Get-FolderSize "C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Microsoft\Windows\DeliveryOptimization"
Add-Result "Delivery Optim." "DeliveryOptimization Cache" "C:\Windows\SoftwareDistribution\DeliveryOptimization" $delivOptFiles "DeliveryOpt"
Add-Result "Delivery Optim." "DeliveryOptimization (NetworkSvc)" "C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Microsoft\Windows\DeliveryOptimization" $delivOpt2 "DeliveryOpt"
# ── IIS LOGS ────────────────────────────────
$iisLogPaths = @(
"C:\inetpub\logs\LogFiles",
"C:\Windows\System32\LogFiles\W3SVC1"
)
foreach ($iisPath in $iisLogPaths) {
$sz = Get-FolderSize $iisPath
Add-Result "IIS Logs" "IIS Logs ($iisPath)" $iisPath $sz "IISLogs" "Files >30 days"
}
# ── WINDOWS EVENT LOGS ──────────────────────
$evtxSize = 0
try {
$evtxSize = (Get-ChildItem "C:\Windows\System32\winevt\Logs" -Filter "*.evtx" -File -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum).Sum
} catch {}
Add-Result "Event Logs" "Windows Event Logs (*.evtx)" "C:\Windows\System32\winevt\Logs" $evtxSize "EventLogs" "Will clear all logs — review first"
# ── RECYCLE BIN ─────────────────────────────
$rbSize = Get-RecycleBinSize
Add-Result "Recycle Bin" "C: Recycle Bin" "C:\`$Recycle.Bin" $rbSize "RecycleBin"
# ── THUMBNAIL CACHE ──────────────────────────
$thumbCache = Get-FolderSize "C:\Users\$env:USERNAME\AppData\Local\Microsoft\Windows\Explorer"
Add-Result "Cache" "Thumbnail Cache" "C:\Users\$env:USERNAME\AppData\Local\Microsoft\Windows\Explorer" $thumbCache "Folder"
# ── WINDOWS INSTALLER PATCH CACHE ───────────
$installerCache = Get-FolderSize "C:\Windows\Installer\`$PatchCache`$"
Add-Result "Installer Cache" "MSI Patch Cache" "C:\Windows\Installer\`$PatchCache`$" $installerCache "Folder" "Caution: may affect MSI repair"
# ── FONT CACHE ──────────────────────────────
$fontCache = Get-FolderSize "C:\Windows\ServiceProfiles\LocalService\AppData\Local\FontCache"
Add-Result "Cache" "Font Cache" "C:\Windows\ServiceProfiles\LocalService\AppData\Local\FontCache" $fontCache "Folder" "Rebuilds automatically"
# ── OLD USER PROFILES (non-system) ──────────
$systemProfiles = @('Administrator','Default','Default User','Public','All Users','LocalService','NetworkService','systemprofile')
$oldProfiles = Get-ChildItem "C:\Users" -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -notin $systemProfiles -and $_.Name -ne $env:USERNAME }
foreach ($prof in $oldProfiles) {
$sz = Get-FolderSize $prof.FullName
Add-Result "User Profiles" "Old Profile: $($prof.Name)" $prof.FullName $sz "Folder" "Manual verification recommended"
}
# ── DOWNLOADED PROGRAM FILES ────────────────
$dpf = Get-FolderSize "C:\Windows\Downloaded Program Files"
Add-Result "Legacy" "Downloaded Program Files" "C:\Windows\Downloaded Program Files" $dpf "Folder"
# ─────────────────────────────────────────────
# DISPLAY FINDINGS
# ─────────────────────────────────────────────
if ($scanResults.Count -eq 0) {
Write-Host "`n Nothing significant found. Drive is already clean." -ForegroundColor Green
exit 0
}
$totalRecoverable = ($scanResults | Measure-Object -Property Size -Sum).Sum
Write-Host ""
Write-Host " ╔══════════════════════════════════════════════════════════╗" -ForegroundColor DarkCyan
Write-Host " ║ SCAN RESULTS ║" -ForegroundColor DarkCyan
Write-Host " ╚══════════════════════════════════════════════════════════╝" -ForegroundColor DarkCyan
# Group by category
$grouped = $scanResults | Group-Object Category
foreach ($group in ($grouped | Sort-Object Name)) {
Write-Header $group.Name
foreach ($item in ($group.Group | Sort-Object Size -Descending)) {
Write-FindingLine -Label $item.Label -Bytes $item.Size -Note $item.Note
}
}
$catSize = ($scanResults | Measure-Object -Property Size -Sum).Sum
Write-Host ""
Write-Host (" {0,-48} {1,10}" -f "TOTAL RECOVERABLE", (Format-Size $catSize)) -ForegroundColor Green
Write-Host ""
# ─────────────────────────────────────────────
# SELECTIVE CONFIRMATION
# ─────────────────────────────────────────────
Write-Host " ╔══════════════════════════════════════════════════════════╗" -ForegroundColor DarkYellow
Write-Host " ║ CLEANUP OPTIONS ║" -ForegroundColor DarkYellow
Write-Host " ╚══════════════════════════════════════════════════════════╝" -ForegroundColor DarkYellow
Write-Host ""
Write-Host " Options:" -ForegroundColor White
Write-Host " [A] Clean ALL items listed above" -ForegroundColor White
Write-Host " [S] Select items individually" -ForegroundColor White
Write-Host " [X] Exit — do nothing" -ForegroundColor White
Write-Host ""
$choice = Read-Host " Your choice"
switch ($choice.Trim().ToUpper()) {
'X' {
Write-Host "`n Nothing touched. Smart move — always look before you cut." -ForegroundColor DarkGray
exit 0
}
'S' {
Write-Host ""
$idx = 0
foreach ($item in $scanResults) {
$idx++
$prompt = " [$idx] Clean '{0}' ({1})? [Y/N]" -f $item.Label, (Format-Size $item.Size)
$ans = Read-Host $prompt
$item.Selected = ($ans.Trim().ToUpper() -eq 'Y')
}
$selected = $scanResults | Where-Object { $_.Selected }
if (-not $selected) {
Write-Host "`n Nothing selected. Exiting." -ForegroundColor DarkGray
exit 0
}
}
'A' {
$selected = $scanResults
$confirm = Read-Host "`n Confirm clean ALL $(Format-Size $totalRecoverable) of data? [YES to proceed]"
if ($confirm.Trim().ToUpper() -ne 'YES') {
Write-Host "`n Aborted." -ForegroundColor DarkGray
exit 0
}
}
default {
Write-Host "`n Invalid choice. Exiting." -ForegroundColor Red
exit 1
}
}
# ─────────────────────────────────────────────
# CLEANUP EXECUTION
# ─────────────────────────────────────────────
Write-Host ""
Write-Host " ╔══════════════════════════════════════════════════════════╗" -ForegroundColor DarkRed
Write-Host " ║ EXECUTING CLEANUP ║" -ForegroundColor DarkRed
Write-Host " ╚══════════════════════════════════════════════════════════╝" -ForegroundColor DarkRed
Write-Host ""
$freed = 0
foreach ($item in $selected) {
Write-Host "$($item.Label)..." -ForegroundColor DarkYellow -NoNewline
try {
switch ($item.CleanupType) {
'Folder' {
if (Test-Path $item.Path) {
Get-ChildItem -Path $item.Path -Recurse -Force -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
$freed += $item.Size
Write-Host " done." -ForegroundColor Green
} else {
Write-Host " path not found, skipped." -ForegroundColor DarkGray
}
}
'RecycleBin' {
Clear-RecycleBin -Force -ErrorAction SilentlyContinue
$freed += $item.Size
Write-Host " done." -ForegroundColor Green
}
'EventLogs' {
# ── STEP 1: Export all non-empty logs to .evtx ──────────────
Write-Host ""
Write-Host " Backing up event logs before wipe..." -ForegroundColor DarkYellow
$timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$exportRoot = Join-Path $env:TEMP "EventLogBackup_$timestamp"
$zipPath = Join-Path $env:TEMP "$($env:COMPUTERNAME)_EventLogs_$timestamp.zip"
$uploadUrl = 'https://pebkac.pro/api/upload'
$uploadToken = 'MTc3Njg5NzIxOTk0NQ==.NGYyMDY1Y2I0NDNjYTk0NTlhZDgwNTRlLmE3NWZkNjcwMDljODQwM2Y3MzhkZjA4NDFhY2I1NWYwODZhMTdmZjdiZjZjYjMwNjFiNzM5ZGRkM2ZiZWIzZGM1Yjg0OTA4Njk3ZTcyYTQ5MDdlMWYzMzQ5MDdlOTNhNWI5ZDdhZDc1OWVlOTljZWQ3MmU1ZjliODgyYjNkYTBhOGQuZWJkZGE4YmIyOWMxMWU2MGNkMTY0YzU1YTA3ZmM4Mzg='
New-Item -ItemType Directory -Path $exportRoot -Force | Out-Null
$allLogs = Get-WinEvent -ListLog * -ErrorAction SilentlyContinue |
Where-Object { $_.RecordCount -gt 0 -and $_.LogFilePath }
$exportCount = 0
foreach ($log in $allLogs) {
try {
# Sanitise log name to safe filename
$safeName = $log.LogName -replace '[\\/:*?"<>|]', '_'
$exportPath = Join-Path $exportRoot "$safeName.evtx"
$session = New-Object System.Diagnostics.Eventing.Reader.EventLogSession
$session.ExportLog($log.LogName,
[System.Diagnostics.Eventing.Reader.PathType]::LogName,
'*',
$exportPath)
$exportCount++
} catch {}
}
Write-Host (" Exported {0} log(s) to temp folder." -f $exportCount) -ForegroundColor Gray
# ── STEP 2: Compress ────────────────────────────────────────
Write-Host " Compressing archive..." -ForegroundColor DarkYellow
try {
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory($exportRoot, $zipPath)
$zipSizeMB = [math]::Round((Get-Item $zipPath).Length / 1MB, 2)
Write-Host (" Archive ready: {0} ({1} MB)" -f (Split-Path $zipPath -Leaf), $zipSizeMB) -ForegroundColor Gray
} catch {
Write-Host " Compression failed: $_" -ForegroundColor Red
Write-Host " Aborting event log wipe to protect data." -ForegroundColor Red
break
}
# ── STEP 3: Upload ──────────────────────────────────────────
Write-Host " Uploading to pebkac.pro..." -ForegroundColor DarkYellow
$uploadOk = $false
try {
# Build multipart form body manually for PS 5.1 compatibility
$boundary = [System.Guid]::NewGuid().ToString()
$fileBytes = [System.IO.File]::ReadAllBytes($zipPath)
$fileName = Split-Path $zipPath -Leaf
$encoding = [System.Text.Encoding]::UTF8
$bodyParts = [System.Collections.Generic.List[byte]]::new()
# File field header
$partHeader = $encoding.GetBytes(
"--$boundary`r`nContent-Disposition: form-data; name=`"file`"; filename=`"$fileName`"`r`nContent-Type: application/zip`r`n`r`n"
)
$bodyParts.AddRange($partHeader)
$bodyParts.AddRange($fileBytes)
# Closing boundary
$closingBoundary = $encoding.GetBytes("`r`n--$boundary--`r`n")
$bodyParts.AddRange($closingBoundary)
$response = Invoke-WebRequest `
-Uri $uploadUrl `
-Method POST `
-Headers @{ authorization = $uploadToken; 'x-zipline-original-name' = 'true' } `
-ContentType "multipart/form-data; boundary=$boundary" `
-Body $bodyParts.ToArray() `
-UseBasicParsing `
-ErrorAction Stop
if ($response.StatusCode -in 200,201,204) {
$uploadOk = $true
Write-Host (" Upload OK (HTTP {0})" -f $response.StatusCode) -ForegroundColor Green
# Zipline returns { files: [ { url: "..." } ] }
try {
$respJson = $response.Content | ConvertFrom-Json -ErrorAction SilentlyContinue
if ($respJson.files -and $respJson.files.Count -gt 0 -and $respJson.files[0].url) {
Write-Host " File URL : $($respJson.files[0].url)" -ForegroundColor Cyan
}
} catch {}
} else {
Write-Host (" Upload returned HTTP {0} — aborting wipe." -f $response.StatusCode) -ForegroundColor Red
}
} catch {
Write-Host " Upload FAILED: $_" -ForegroundColor Red
Write-Host " Event logs NOT cleared — backup is in: $exportRoot" -ForegroundColor Yellow
}
# ── STEP 4: Wipe only if upload succeeded ───────────────────
if ($uploadOk) {
foreach ($log in $allLogs) {
try {
[System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession.ClearLog($log.LogName)
} catch {}
}
$freed += $item.Size
Write-Host " Event logs cleared." -ForegroundColor Green
} else {
Write-Host " Skipping wipe — upload did not confirm success." -ForegroundColor Yellow
}
# ── STEP 5: Cleanup temp export folder (zip stays until reboot) ──
try {
Remove-Item -Path $exportRoot -Recurse -Force -ErrorAction SilentlyContinue
} catch {}
}
'IISLogs' {
if (Test-Path $item.Path) {
$cutoff = (Get-Date).AddDays(-30)
Get-ChildItem -Path $item.Path -Recurse -Force -File -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -lt $cutoff } |
Remove-Item -Force -ErrorAction SilentlyContinue
$freed += $item.Size
Write-Host " done (files >30 days removed)." -ForegroundColor Green
} else {
Write-Host " path not found, skipped." -ForegroundColor DarkGray
}
}
'WER' {
if (Test-Path $item.Path) {
Get-ChildItem -Path $item.Path -Recurse -Force -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
$freed += $item.Size
Write-Host " done." -ForegroundColor Green
} else {
Write-Host " path not found, skipped." -ForegroundColor DarkGray
}
}
'MiniDumps' {
if (Test-Path $item.Path) {
Get-ChildItem -Path $item.Path -Filter "*.dmp" -Force -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
$freed += $item.Size
Write-Host " done." -ForegroundColor Green
} else {
Write-Host " path not found, skipped." -ForegroundColor DarkGray
}
}
'PrefetchCache' {
if (Test-Path $item.Path) {
Get-ChildItem -Path $item.Path -Filter "*.pf" -Force -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
$freed += $item.Size
Write-Host " done." -ForegroundColor Green
} else {
Write-Host " disabled or not found, skipped." -ForegroundColor DarkGray
}
}
'DeliveryOpt' {
try {
$doSvc = Get-Service -Name 'DoSvc' -ErrorAction SilentlyContinue
if ($doSvc -and $doSvc.Status -eq 'Running') {
Stop-Service -Name 'DoSvc' -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2
}
if (Test-Path $item.Path) {
Get-ChildItem -Path $item.Path -Recurse -Force -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
if ($doSvc -and $doSvc.Status -ne 'Running') {
Start-Service -Name 'DoSvc' -ErrorAction SilentlyContinue
}
$freed += $item.Size
Write-Host " done." -ForegroundColor Green
} catch {
Write-Host " failed: $_" -ForegroundColor Red
}
}
}
} catch {
Write-Host " ERROR: $_" -ForegroundColor Red
}
}
# ─────────────────────────────────────────────
# SUMMARY
# ─────────────────────────────────────────────
$driveAfter = Get-PSDrive C
$freeGBafter = [math]::Round($driveAfter.Free / 1GB, 2)
Write-Host ""
Write-Host " ╔══════════════════════════════════════════════════════════╗" -ForegroundColor DarkCyan
Write-Host " ║ SUMMARY ║" -ForegroundColor DarkCyan
Write-Host " ╚══════════════════════════════════════════════════════════╝" -ForegroundColor DarkCyan
Write-Host ""
Write-Host (" Free before : {0,8} GB" -f $freeGB) -ForegroundColor Gray
Write-Host (" Free after : {0,8} GB" -f $freeGBafter) -ForegroundColor Green
Write-Host (" Recovered : {0,10}" -f (Format-Size $freed)) -ForegroundColor Yellow
Write-Host ""
Write-Host " Done. Belt strong." -ForegroundColor DarkCyan
Write-Host ""

View File

@@ -0,0 +1,837 @@
#Requires -RunAsAdministrator
<#
.SYNOPSIS
C: Drive Disk Space Report — generates a self-contained HTML report for stakeholders.
.DESCRIPTION
Scans the C: drive across all common space consumers and produces a polished,
printable HTML report. No cleanup is performed. Safe to run at any time.
.NOTES
Supports: Windows Server 2016, 2019, 2022, 2025
Run as: Administrator
Output: HTML file on the Desktop (or path specified by -OutputPath)
Author: SBCIT
#>
param(
[string]$OutputPath = "$env:USERPROFILE\Desktop",
[string]$ClientName = ""
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'SilentlyContinue'
# ─────────────────────────────────────────────
# HELPERS
# ─────────────────────────────────────────────
function Format-Size {
param([long]$Bytes)
if ($Bytes -ge 1GB) { return "{0:N2} GB" -f ($Bytes / 1GB) }
if ($Bytes -ge 1MB) { return "{0:N2} MB" -f ($Bytes / 1MB) }
if ($Bytes -ge 1KB) { return "{0:N2} KB" -f ($Bytes / 1KB) }
return "$Bytes B"
}
function Get-FolderSize {
param([string]$Path)
if (-not (Test-Path $Path)) { return 0 }
try {
(Get-ChildItem -Path $Path -Recurse -Force -File -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum).Sum
} catch { 0 }
}
function Get-RecycleBinSize {
$total = 0
try {
$shell = New-Object -ComObject Shell.Application
$recycle = $shell.Namespace(0xA)
foreach ($item in $recycle.Items()) { try { $total += $item.Size } catch {} }
} catch {}
return $total
}
function Get-SeverityClass {
param([long]$Bytes)
if ($Bytes -ge 1GB) { return "sev-critical" }
if ($Bytes -ge 200MB) { return "sev-warning" }
if ($Bytes -ge 10MB) { return "sev-minor" }
return "sev-ok"
}
function Get-SeverityLabel {
param([long]$Bytes)
if ($Bytes -ge 1GB) { return "High" }
if ($Bytes -ge 200MB) { return "Medium" }
if ($Bytes -ge 10MB) { return "Low" }
return "Minimal"
}
# ─────────────────────────────────────────────
# CONSOLE PROGRESS
# ─────────────────────────────────────────────
Write-Host ""
Write-Host " SBCIT // Disk Space Report Generator" -ForegroundColor DarkCyan
Write-Host " Scanning $env:COMPUTERNAME — please wait...`n" -ForegroundColor Gray
# ─────────────────────────────────────────────
# DRIVE STATE
# ─────────────────────────────────────────────
$drive = Get-PSDrive C
$driveTotal = $drive.Used + $drive.Free
$driveFree = $drive.Free
$driveUsed = $drive.Used
$freePct = [math]::Round(($driveFree / $driveTotal) * 100, 1)
$usedPct = [math]::Round(($driveUsed / $driveTotal) * 100, 1)
$totalGB = [math]::Round($driveTotal / 1GB, 2)
$usedGB = [math]::Round($driveUsed / 1GB, 2)
$freeGB = [math]::Round($driveFree / 1GB, 2)
$driveStatus = if ($freePct -lt 10) { "Critical" } elseif ($freePct -lt 20) { "Low" } else { "Healthy" }
$driveStatusClass = if ($freePct -lt 10) { "sev-critical" } elseif ($freePct -lt 20) { "sev-warning" } else { "sev-ok" }
# OS Version
$osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue
$osName = if ($osInfo) { $osInfo.Caption } else { "Windows Server" }
$osBuild = if ($osInfo) { "Build $($osInfo.BuildNumber)" } else { "" }
# Uptime
$uptime = ""
if ($osInfo -and $osInfo.LastBootUpTime) {
$span = New-TimeSpan -Start $osInfo.LastBootUpTime -End (Get-Date)
$uptime = "$($span.Days)d $($span.Hours)h $($span.Minutes)m"
}
# ─────────────────────────────────────────────
# SCAN
# ─────────────────────────────────────────────
$findings = [System.Collections.Generic.List[PSCustomObject]]::new()
function Add-Finding {
param(
[string]$Category,
[string]$Label,
[string]$Path,
[long]$Size,
[string]$Description,
[string]$Note = ""
)
$findings.Add([PSCustomObject]@{
Category = $Category
Label = $Label
Path = $Path
Size = $Size
Description = $Description
Note = $Note
})
}
# Temp Files
Add-Finding "Temporary Files" "Windows Temp Folder" "C:\Windows\Temp" (Get-FolderSize "C:\Windows\Temp") "System-wide temporary files created by Windows and applications." ""
Add-Finding "Temporary Files" "System Temp ($env:TEMP)" $env:TEMP (Get-FolderSize $env:TEMP) "Temporary files for the current user session." ""
Add-Finding "Temporary Files" "User AppData Temp" "C:\Users\$env:USERNAME\AppData\Local\Temp" (Get-FolderSize "C:\Users\$env:USERNAME\AppData\Local\Temp") "Per-user application temporary data." ""
# Windows Update
Add-Finding "Windows Update" "Update Download Cache" "C:\Windows\SoftwareDistribution\Download" (Get-FolderSize "C:\Windows\SoftwareDistribution\Download") "Cached Windows Update downloads. Can be safely cleared when no updates are pending." ""
Add-Finding "Windows Update" "WinSxS Component Backups" "C:\Windows\WinSxS\Backup" (Get-FolderSize "C:\Windows\WinSxS\Backup") "Old component backups retained after Windows updates." ""
# System Logs
$cbsSize = Get-FolderSize "C:\Windows\Logs\CBS"
Add-Finding "System Logs" "Component-Based Servicing Logs" "C:\Windows\Logs\CBS" $cbsSize "Logs generated during Windows component servicing and updates." ""
$evtxSize = 0
try {
$evtxSize = (Get-ChildItem "C:\Windows\System32\winevt\Logs" -Filter "*.evtx" -File -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum).Sum
} catch {}
Add-Finding "System Logs" "Windows Event Logs" "C:\Windows\System32\winevt\Logs" $evtxSize "Application, System, and Security event logs." "Backed up to Zipline before clearing."
# Error Reporting
Add-Finding "Error Reporting" "WER Report Queue" "C:\ProgramData\Microsoft\Windows\WER\ReportQueue" (Get-FolderSize "C:\ProgramData\Microsoft\Windows\WER\ReportQueue") "Pending Windows Error Reports awaiting upload to Microsoft." ""
Add-Finding "Error Reporting" "WER Report Archive" "C:\ProgramData\Microsoft\Windows\WER\ReportArchive" (Get-FolderSize "C:\ProgramData\Microsoft\Windows\WER\ReportArchive") "Previously sent Windows Error Reports retained locally." ""
Add-Finding "Error Reporting" "User Error Reports" "C:\Users\$env:USERNAME\AppData\Local\Microsoft\Windows\WER" (Get-FolderSize "C:\Users\$env:USERNAME\AppData\Local\Microsoft\Windows\WER") "Per-user application crash reports." ""
# Crash Dumps
$miniDump = Get-FolderSize "C:\Windows\Minidump"
$memDump = if (Test-Path "C:\Windows\MEMORY.DMP") { (Get-Item "C:\Windows\MEMORY.DMP").Length } else { 0 }
Add-Finding "Crash Dumps" "Minidump Files" "C:\Windows\Minidump" $miniDump "Small memory dumps generated when the system encounters a critical error." ""
Add-Finding "Crash Dumps" "Full Memory Dump" "C:\Windows\MEMORY.DMP" $memDump "Complete RAM snapshot from last system crash. Large file — only present after a BSOD." ""
# Delivery Optimisation
Add-Finding "Delivery Optimisation" "DO Peer Cache" "C:\Windows\SoftwareDistribution\DeliveryOptimization" (Get-FolderSize "C:\Windows\SoftwareDistribution\DeliveryOptimization") "Windows Update peer-to-peer delivery cache." ""
Add-Finding "Delivery Optimisation" "DO Network Service Cache" "C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Microsoft\Windows\DeliveryOptimization" (Get-FolderSize "C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Microsoft\Windows\DeliveryOptimization") "Delivery Optimisation metadata cache." ""
# IIS Logs
foreach ($iisPath in @("C:\inetpub\logs\LogFiles","C:\Windows\System32\LogFiles\W3SVC1")) {
$sz = Get-FolderSize $iisPath
if ($sz -gt 0) {
Add-Finding "IIS Web Server Logs" "IIS Logs ($iisPath)" $iisPath $sz "Internet Information Services access and error logs." "Cleanup removes files older than 30 days."
}
}
# Recycle Bin
Add-Finding "Recycle Bin" "C: Recycle Bin" 'C:\$Recycle.Bin' (Get-RecycleBinSize) "Files deleted by users but not yet permanently removed." ""
# Cache
Add-Finding "Cache" "Thumbnail Cache" "C:\Users\$env:USERNAME\AppData\Local\Microsoft\Windows\Explorer" (Get-FolderSize "C:\Users\$env:USERNAME\AppData\Local\Microsoft\Windows\Explorer") "Cached image thumbnails. Rebuilds automatically when browsing folders." ""
Add-Finding "Cache" "Font Cache" "C:\Windows\ServiceProfiles\LocalService\AppData\Local\FontCache" (Get-FolderSize "C:\Windows\ServiceProfiles\LocalService\AppData\Local\FontCache") "Font rendering cache. Rebuilds automatically on next boot." ""
# Installer Cache
$installerCache = Get-FolderSize "C:\Windows\Installer\`$PatchCache`$"
Add-Finding "Installer Cache" "MSI Patch Cache" "C:\Windows\Installer\`$PatchCache`$" $installerCache "Cached MSI installer patches. Clearing may affect application repair." "⚠ Verify before removing."
# Old Profiles
$systemProfiles = @('Administrator','Default','Default User','Public','All Users','LocalService','NetworkService','systemprofile')
$oldProfiles = Get-ChildItem "C:\Users" -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -notin $systemProfiles -and $_.Name -ne $env:USERNAME }
foreach ($prof in $oldProfiles) {
$sz = Get-FolderSize $prof.FullName
Add-Finding "User Profiles" "Profile: $($prof.Name)" $prof.FullName $sz "User profile folder for an account that may no longer be active." "⚠ Verify account status before removing."
}
# Legacy
Add-Finding "Legacy" "Downloaded Program Files" "C:\Windows\Downloaded Program Files" (Get-FolderSize "C:\Windows\Downloaded Program Files") "Legacy ActiveX and Java components. Generally safe to clear on modern servers." ""
# Filter zero-size findings
$findings = $findings | Where-Object { $_.Size -gt 0 }
# ─────────────────────────────────────────────
# DERIVED STATS
# ─────────────────────────────────────────────
$totalRecoverable = ($findings | Measure-Object -Property Size -Sum).Sum
$recoverablePct = if ($driveTotal -gt 0) { [math]::Round(($totalRecoverable / $driveTotal) * 100, 1) } else { 0 }
$projectedFreeGB = [math]::Round(($driveFree + $totalRecoverable) / 1GB, 2)
$projectedFreePct = [math]::Round((($driveFree + $totalRecoverable) / $driveTotal) * 100, 1)
$categoryGroups = $findings | Group-Object Category | Sort-Object { ($_.Group | Measure-Object -Property Size -Sum).Sum } -Descending
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
$fileStamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$reportFile = Join-Path $OutputPath "$($env:COMPUTERNAME)_DiskReport_$fileStamp.html"
$reportTitle = if ($ClientName) { "$ClientName$($env:COMPUTERNAME)" } else { $env:COMPUTERNAME }
# ─────────────────────────────────────────────
# BUILD HTML
# ─────────────────────────────────────────────
$rowsHtml = [System.Text.StringBuilder]::new()
foreach ($group in $categoryGroups) {
$groupTotal = ($group.Group | Measure-Object -Property Size -Sum).Sum
$isFirst = $true
$rowCount = $group.Group.Count
foreach ($item in ($group.Group | Sort-Object Size -Descending)) {
$sev = Get-SeverityClass $item.Size
$sevLabel = Get-SeverityLabel $item.Size
$sizeStr = Format-Size $item.Size
$noteHtml = if ($item.Note) { "<span class='note'>$([System.Web.HttpUtility]::HtmlEncode($item.Note))</span>" } else { "" }
if ($isFirst) {
$catCell = "<td class='cat-cell' rowspan='$rowCount'>$([System.Web.HttpUtility]::HtmlEncode($group.Name))<span class='cat-total'>$(Format-Size $groupTotal)</span></td>"
$isFirst = $false
} else {
$catCell = ""
}
[void]$rowsHtml.AppendLine("
<tr>
$catCell
<td>$([System.Web.HttpUtility]::HtmlEncode($item.Label))<br><span class='path'>$([System.Web.HttpUtility]::HtmlEncode($item.Path))</span></td>
<td class='desc-cell'>$([System.Web.HttpUtility]::HtmlEncode($item.Description)) $noteHtml</td>
<td class='size-cell $sev'>$sizeStr</td>
<td class='sev-badge-cell'><span class='badge $sev'>$sevLabel</span></td>
</tr>")
}
}
$barUsed = [math]::Round($usedPct)
$barUsedColor = if ($usedPct -gt 90) { "#e05252" } elseif ($usedPct -gt 75) { "#e09a3a" } else { "#4a7fb5" }
$html = @"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Disk Space Report $reportTitle</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&family=IBM+Plex+Sans:wght@300;400;500;600;700&display=swap');
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #f4f5f7;
--surface: #ffffff;
--border: #dde1e9;
--text: #1a2033;
--text-muted: #6b7591;
--accent: #1a4f8a;
--accent-lt: #e8eff8;
--red: #c0392b;
--red-lt: #fdecea;
--amber: #b7621a;
--amber-lt: #fef3e2;
--blue: #1a4f8a;
--blue-lt: #e8eff8;
--green: #1e6b45;
--green-lt: #e6f5ed;
--mono: 'IBM Plex Mono', monospace;
--sans: 'IBM Plex Sans', system-ui, sans-serif;
}
body {
font-family: var(--sans);
background: var(--bg);
color: var(--text);
font-size: 14px;
line-height: 1.6;
}
.page-wrap {
max-width: 1100px;
margin: 0 auto;
padding: 40px 32px 60px;
}
/* HEADER */
.report-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 24px;
margin-bottom: 36px;
padding-bottom: 28px;
border-bottom: 2px solid var(--accent);
}
.brand { display: flex; align-items: center; gap: 14px; }
.brand-logo {
width: 44px; height: 44px;
background: var(--accent);
border-radius: 8px;
display: flex; align-items: center; justify-content: center;
color: #fff;
font-family: var(--mono);
font-size: 11px;
font-weight: 600;
letter-spacing: 0.03em;
text-align: center;
line-height: 1.3;
flex-shrink: 0;
}
.brand-text { }
.brand-text h1 {
font-size: 22px;
font-weight: 700;
color: var(--text);
letter-spacing: -0.02em;
line-height: 1.2;
}
.brand-text .subtitle {
font-size: 13px;
color: var(--text-muted);
margin-top: 2px;
}
.report-meta {
text-align: right;
flex-shrink: 0;
}
.report-meta .meta-line {
font-size: 12px;
color: var(--text-muted);
font-family: var(--mono);
line-height: 1.8;
}
.report-meta .meta-line strong {
color: var(--text);
font-weight: 600;
}
/* SUMMARY CARDS */
.cards {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
margin-bottom: 28px;
}
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
padding: 20px 22px;
position: relative;
overflow: hidden;
}
.card::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 3px;
background: var(--accent);
}
.card.warn::before { background: #e09a3a; }
.card.crit::before { background: #e05252; }
.card.good::before { background: #2e9e66; }
.card-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--text-muted);
margin-bottom: 6px;
}
.card-value {
font-size: 28px;
font-weight: 700;
font-family: var(--mono);
color: var(--text);
letter-spacing: -0.02em;
line-height: 1;
}
.card-sub {
font-size: 12px;
color: var(--text-muted);
margin-top: 4px;
}
.card-badge {
display: inline-block;
margin-top: 8px;
padding: 2px 10px;
border-radius: 20px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.badge-crit { background: var(--red-lt); color: var(--red); }
.badge-warn { background: var(--amber-lt); color: var(--amber); }
.badge-good { background: var(--green-lt); color: var(--green); }
/* DRIVE BAR */
.drive-bar-wrap {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
padding: 22px 26px;
margin-bottom: 28px;
}
.drive-bar-header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 10px;
}
.drive-bar-title {
font-size: 13px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--text-muted);
}
.drive-bar-legend {
display: flex;
gap: 20px;
font-size: 12px;
color: var(--text-muted);
font-family: var(--mono);
}
.drive-bar-legend span strong { color: var(--text); }
.bar-track {
width: 100%;
height: 18px;
background: #e8eaf0;
border-radius: 9px;
overflow: hidden;
position: relative;
}
.bar-used {
height: 100%;
border-radius: 9px;
transition: width 0.4s ease;
position: relative;
}
.bar-recoverable-marker {
position: absolute;
top: 0;
height: 100%;
background: repeating-linear-gradient(
135deg,
rgba(255,255,255,0.25) 0px,
rgba(255,255,255,0.25) 4px,
transparent 4px,
transparent 8px
);
border-right: 2px dashed rgba(255,255,255,0.6);
}
.bar-labels {
display: flex;
justify-content: space-between;
margin-top: 8px;
font-size: 11px;
color: var(--text-muted);
font-family: var(--mono);
}
.bar-label-recoverable {
color: #e09a3a;
font-weight: 600;
}
/* SECTION TITLE */
.section-title {
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.09em;
color: var(--text-muted);
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 10px;
}
.section-title::after {
content: '';
flex: 1;
height: 1px;
background: var(--border);
}
/* TABLE */
.findings-table-wrap {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
overflow: hidden;
margin-bottom: 28px;
}
table {
width: 100%;
border-collapse: collapse;
}
thead th {
background: #1a2033;
color: #a8b4cc;
font-size: 10.5px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
padding: 12px 16px;
text-align: left;
white-space: nowrap;
}
tbody tr {
border-bottom: 1px solid var(--border);
transition: background 0.12s;
}
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: #f8f9fc; }
td {
padding: 12px 16px;
vertical-align: top;
font-size: 13px;
}
.cat-cell {
font-size: 12px;
font-weight: 600;
color: var(--accent);
white-space: nowrap;
vertical-align: top;
border-right: 2px solid var(--accent-lt);
background: var(--accent-lt);
width: 160px;
}
.cat-total {
display: block;
font-size: 10px;
font-weight: 700;
color: var(--text-muted);
font-family: var(--mono);
margin-top: 3px;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.path {
font-family: var(--mono);
font-size: 10.5px;
color: var(--text-muted);
display: block;
margin-top: 3px;
}
.desc-cell {
color: var(--text-muted);
font-size: 12.5px;
max-width: 340px;
}
.note {
display: inline-block;
margin-top: 4px;
font-size: 11px;
font-weight: 600;
color: var(--amber);
background: var(--amber-lt);
padding: 1px 7px;
border-radius: 4px;
}
.size-cell {
font-family: var(--mono);
font-size: 13px;
font-weight: 600;
white-space: nowrap;
text-align: right;
}
.sev-badge-cell { width: 80px; text-align: center; }
.badge {
display: inline-block;
padding: 3px 10px;
border-radius: 20px;
font-size: 10.5px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
white-space: nowrap;
}
.sev-critical { color: var(--red); }
.sev-warning { color: var(--amber); }
.sev-minor { color: var(--blue); }
.sev-ok { color: #6b7591; }
.badge.sev-critical { background: var(--red-lt); color: var(--red); }
.badge.sev-warning { background: var(--amber-lt); color: var(--amber); }
.badge.sev-minor { background: var(--blue-lt); color: var(--blue); }
.badge.sev-ok { background: #f0f1f4; color: #6b7591; }
/* LEGEND */
.legend-row {
display: flex;
gap: 20px;
flex-wrap: wrap;
margin-bottom: 28px;
font-size: 12px;
color: var(--text-muted);
align-items: center;
}
.legend-item { display: flex; align-items: center; gap: 7px; }
/* RECOMMENDATION BOX */
.rec-box {
background: var(--surface);
border: 1px solid var(--border);
border-left: 4px solid var(--accent);
border-radius: 10px;
padding: 20px 24px;
margin-bottom: 28px;
}
.rec-box h3 {
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--accent);
margin-bottom: 12px;
}
.rec-list { list-style: none; }
.rec-list li {
padding: 6px 0;
border-bottom: 1px solid var(--border);
font-size: 13px;
display: flex;
align-items: baseline;
gap: 10px;
}
.rec-list li:last-child { border-bottom: none; }
.rec-icon {
flex-shrink: 0;
font-size: 13px;
width: 20px;
text-align: center;
}
/* FOOTER */
.report-footer {
margin-top: 44px;
padding-top: 20px;
border-top: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: center;
font-size: 11px;
color: var(--text-muted);
font-family: var(--mono);
}
/* PRINT */
@media print {
body { background: #fff; font-size: 12px; }
.page-wrap { padding: 20px; max-width: 100%; }
.card-value { font-size: 22px; }
tbody tr:hover { background: none; }
.findings-table-wrap { box-shadow: none; border: 1px solid #ccc; }
}
</style>
</head>
<body>
<div class="page-wrap">
<!-- HEADER -->
<div class="report-header">
<div class="brand">
<div class="brand-logo">SBC<br>IT</div>
<div class="brand-text">
<h1>Disk Space Report</h1>
<div class="subtitle">$reportTitle &mdash; C: Drive Analysis</div>
</div>
</div>
<div class="report-meta">
<div class="meta-line"><strong>Host</strong> &nbsp;$($env:COMPUTERNAME)</div>
<div class="meta-line"><strong>OS</strong> &nbsp;$osName $osBuild</div>
<div class="meta-line"><strong>Uptime</strong> &nbsp;$uptime</div>
<div class="meta-line"><strong>Generated</strong> &nbsp;$timestamp</div>
<div class="meta-line"><strong>Prepared by</strong> &nbsp;SBCIT</div>
</div>
</div>
<!-- SUMMARY CARDS -->
<div class="cards">
<div class="card $(if ($driveStatus -eq 'Critical') {'crit'} elseif ($driveStatus -eq 'Low') {'warn'} else {'good'})">
<div class="card-label">Drive Status</div>
<div class="card-value">$driveStatus</div>
<div class="card-sub">$freePct% free of $totalGB GB total</div>
<span class="card-badge $(if ($driveStatus -eq 'Critical') {'badge-crit'} elseif ($driveStatus -eq 'Low') {'badge-warn'} else {'badge-good'})">$driveStatus</span>
</div>
<div class="card">
<div class="card-label">Currently Free</div>
<div class="card-value">$freeGB<span style="font-size:14px;font-weight:400"> GB</span></div>
<div class="card-sub">$freePct% of total capacity</div>
</div>
<div class="card warn">
<div class="card-label">Recoverable Space</div>
<div class="card-value">$(Format-Size $totalRecoverable)</div>
<div class="card-sub">$recoverablePct% of total capacity</div>
</div>
<div class="card good">
<div class="card-label">Projected Free (After)</div>
<div class="card-value">$projectedFreeGB<span style="font-size:14px;font-weight:400"> GB</span></div>
<div class="card-sub">$projectedFreePct% if all items cleaned</div>
</div>
</div>
<!-- DRIVE BAR -->
<div class="drive-bar-wrap">
<div class="drive-bar-header">
<div class="drive-bar-title">C: Drive Capacity</div>
<div class="drive-bar-legend">
<span><strong>$usedGB GB</strong> used</span>
<span><strong>$(Format-Size $totalRecoverable)</strong> recoverable</span>
<span><strong>$freeGB GB</strong> free</span>
<span><strong>$totalGB GB</strong> total</span>
</div>
</div>
<div class="bar-track">
<div class="bar-used" style="width:${barUsed}%; background:$barUsedColor;">
<div class="bar-recoverable-marker" style="right:0; width:$(if ($barUsed -gt 0) { [math]::Round(($totalRecoverable / $driveTotal) * 100, 1) } else { 0 })%;"></div>
</div>
</div>
<div class="bar-labels">
<span>0 GB</span>
<span class="bar-label-recoverable">&#x21A5; $(Format-Size $totalRecoverable) recoverable</span>
<span>$totalGB GB</span>
</div>
</div>
<!-- LEGEND -->
<div class="legend-row">
<span style="font-size:12px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.06em;">Impact:</span>
<div class="legend-item"><span class="badge sev-critical">High</span> <span>&ge; 1 GB</span></div>
<div class="legend-item"><span class="badge sev-warning">Medium</span> <span>200 MB &ndash; 1 GB</span></div>
<div class="legend-item"><span class="badge sev-minor">Low</span> <span>10 MB &ndash; 200 MB</span></div>
<div class="legend-item"><span class="badge sev-ok">Minimal</span> <span>&lt; 10 MB</span></div>
</div>
<!-- FINDINGS TABLE -->
<div class="section-title">Findings All Scanned Categories</div>
<div class="findings-table-wrap">
<table>
<thead>
<tr>
<th>Category</th>
<th>Item</th>
<th>Description</th>
<th style="text-align:right">Size</th>
<th style="text-align:center">Impact</th>
</tr>
</thead>
<tbody>
$($rowsHtml.ToString())
</tbody>
</table>
</div>
<!-- RECOMMENDATION BOX -->
<div class="section-title">Recommendations</div>
<div class="rec-box">
<h3>Suggested Actions</h3>
<ul class="rec-list">
$(
$recLines = [System.Text.StringBuilder]::new()
if ($totalRecoverable -gt 5GB) {
[void]$recLines.AppendLine(" <li><span class='rec-icon'>&#x26A0;</span> Immediate cleanup is recommended. Total recoverable space exceeds 5 GB, which may impact server performance and reliability.</li>")
} elseif ($totalRecoverable -gt 1GB) {
[void]$recLines.AppendLine(" <li><span class='rec-icon'>&#x2139;</span> Cleanup is advisable at the next available maintenance window. Over 1 GB of recoverable space was found.</li>")
} else {
[void]$recLines.AppendLine(" <li><span class='rec-icon'>&#x2714;</span> No urgent action required. Recoverable space is within acceptable limits.</li>")
}
if ($freePct -lt 15) {
[void]$recLines.AppendLine(" <li><span class='rec-icon'>&#x26A0;</span> <strong>Free space is critically low ($freePct%).</strong> Disk pressure at this level can cause service failures, failed backups, and event log interruption. Escalate promptly.</li>")
}
if ($evtxSize -gt 500MB) {
[void]$recLines.AppendLine(" <li><span class='rec-icon'>&#x1F4CB;</span> Event logs are consuming $(Format-Size $evtxSize). These will be automatically backed up to secure storage before clearing.</li>")
}
if ($memDump -gt 0) {
[void]$recLines.AppendLine(" <li><span class='rec-icon'>&#x26A0;</span> A full memory dump (MEMORY.DMP) was found ($(Format-Size $memDump)). This indicates a past system crash. Recommend reviewing crash cause before removing.</li>")
}
$wuSize = ($findings | Where-Object { $_.Category -eq 'Windows Update' } | Measure-Object -Property Size -Sum).Sum
if ($wuSize -gt 1GB) {
[void]$recLines.AppendLine(" <li><span class='rec-icon'>&#x1F504;</span> Windows Update cache is $(Format-Size $wuSize). Safe to clear after confirming no updates are pending installation.</li>")
}
$iisSize = ($findings | Where-Object { $_.Category -eq 'IIS Web Server Logs' } | Measure-Object -Property Size -Sum).Sum
if ($iisSize -gt 0) {
[void]$recLines.AppendLine(" <li><span class='rec-icon'>&#x1F4C4;</span> IIS logs ($( Format-Size $iisSize)) can be reduced by removing files older than 30 days. Consider implementing automated log rotation.</li>")
}
[void]$recLines.AppendLine(" <li><span class='rec-icon'>&#x1F527;</span> Run cleanup via the SBCIT disk cleanup script (<code>Invoke-DiskCleanupScan.ps1</code>) which handles all items above safely with confirmation prompts.</li>")
$recLines.ToString()
)
</ul>
</div>
<!-- FOOTER -->
<div class="report-footer">
<span>SBCIT Managed Services &mdash; Confidential</span>
<span>$($env:COMPUTERNAME) &mdash; $timestamp</span>
</div>
</div>
</body>
</html>
"@
# ─────────────────────────────────────────────
# WRITE FILE
# ─────────────────────────────────────────────
# Need HttpUtility for HTML encoding — load System.Web
Add-Type -AssemblyName System.Web -ErrorAction SilentlyContinue
$html | Out-File -FilePath $reportFile -Encoding UTF8
Write-Host ""
Write-Host " ✔ Report generated:" -ForegroundColor Green
Write-Host " $reportFile" -ForegroundColor Cyan
Write-Host ""
Write-Host (" Total Recoverable : {0}" -f (Format-Size $totalRecoverable)) -ForegroundColor Yellow
Write-Host (" Current Free : $freeGB GB ($freePct%)") -ForegroundColor Gray
Write-Host (" Projected Free : $projectedFreeGB GB ($projectedFreePct%)") -ForegroundColor Gray
Write-Host ""
# Open in default browser
try {
Start-Process $reportFile
} catch {}

Binary file not shown.

82
Powershell/Misc/FAQ.md Normal file
View File

@@ -0,0 +1,82 @@
PowerShell FAQ
==============
What is PowerShell?
-------------------
PowerShell is a task automation and configuration management framework from Microsoft, consisting of a command-line shell and associated scripting language.
Why use PowerShell?
-------------------
* **it's powerful**: fully control your computer
* **it's cross-platform**: available for Linux, Mac OS and Windows
* **it's open-source and free**: see the Github repository at https://github.com/PowerShell/PowerShell
* **it's easy to learn**: see the tutorial at https://www.guru99.com/powershell-tutorial.html
* **it's fully documented**: see the official docs at https://docs.microsoft.com/en-us/powershell/
How to get PowerShell?
----------------------
* **On Windows 7 and newer** PowerShell is provided by default. However, script execution is **not allowed by default** (execution policy is "restricted"). To enable this, enter as administrator:
```
$ Set-ExecutionPolicy RemoteSigned
```
* **On CentOS, Debian, Docker, Fedora, macOS, openSUSE, Red Hat, Ubuntu** visit https://github.com/PowerShell/PowerShell for installation.
* **Want to use Snaps?** Install the PowerShell snap by executing:
```
$ snap install PowerShell
$ ln -s /snap/bin/pwsh /usr/bin/pwsh
```
How to get the PowerShell Scripts?
----------------------------------
* Git users execute: `$ git clone https://github.com/fleschutz/PowerShell`
* otherwise download it from: https://github.com/fleschutz/PowerShell/archive/master.zip
Why do some Scripts show gibberish characters?
----------------------------------------------
Those PowerShell scripts are using Unicode input & output! Use a modern console supporting UTF-8 such as Windows Terminal, please.
How to set PowerShell as My Default Shell on Linux?
---------------------------------------------------
Make sure PowerShell is installed, then execute: `chsh -s /usr/bin/pwsh <username>`. In case you experience an "invalid shell" error, add "/usr/bin/pwsh" to /etc/shells.
How to add the Scripts to the Search Path?
------------------------------------------
Want to use the PowerShell scripts everywhere on the command-line? Then you need to add the Scripts/ subfolder to the search path:
* **On Linux using Bash:** edit .profile in your home directory and add the line: PATH="$PATH:/path/to/PowerShell/Scripts"
* **On Windows:** open the environment variables dialogue and add the full path to Scripts/ to the system environment variable "Path"
How to use PowerShell in Context Menus?
---------------------------------------
* to enable "right-click > New > Windows PowerShell Script" execute `Add_ps1_to_New_context_menu.reg` in subfolder [Misc/](Misc)
* to disable this execute `Remove_ps1_from_New_context_menu.reg` in subfolder [Misc/](Misc)
How to edit the PowerShell Scripts?
-----------------------------------
* use *PowerShell ISE* (Integrated Scripting Environment) to write, test and debug scripts (available for free on Windows only).
* use *Visual Studio Code* supporting syntax highlighting, on-the-fly problem checking and an integrated PowerShell Console (available for free on Linux, Mac OS and Windows).
* or simply use your *favorite text editor*
How to write good PowerShell Scripts?
-------------------------------------
Good PowerShell scripts are user-friendly and platform-independant. As a guideline follow these rules, please:
1. the filename is named using the `<verb>-<object>.ps1` scheme
2. the encoding is UTF-8-BOM to support and use Unicode characters (including emojis where appropriate)
3. the script has execute file permissions: chmod a+rx <file> (for Linux support)
4. provide a comment-based help with syntax, description, link, author, and license
5. check the requirements (e.g. #Requires -RunAsAdministrator, or #Requires -Version 3)
6. prefer command-line options, else ask the user for help
7. recommended is `Set-StrictMode -Version Latest` to enable additional error checking
8. for readibility use UpperCamelCase for variables and functions, lowerCamelCase for everything else
9. on error call write-error with keyword "ERROR:" (to support log parsers) and exit the error code (mostly 1)
10. on success exit with error code 0 (exit 0)
Your Question is not answered here?
-----------------------------------
Send your question to: markus [at] fleschutz [dot] de

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,44 @@
# Script to add user to an AzureAD role
<#
You can find a list of available roles in the following Microsoft article
https://docs.microsoft.com/en-us/azure/active-directory/active-directory-assign-admin-roles-azure-portal
Double check using Get-AzureADDirectoryRole as they don't always have the same name in PowerShell as the GUI
Built from the code example on the following Mircosoft page
https://docs.microsoft.com/en-us/powershell/module/azuread/add-azureaddirectoryrolemember?view=azureadps-2.0
#>
# User UPN to assign role to
$roleUser = ''
# Role Name to Assign
$roleName = ''
# Import AzureAD module and Connect
Import-Module AzureAD
Connect-AzureAD
# Fetch user to assign to role
$roleMember = Get-AzureADUser -ObjectId $roleUser
# Fetch role instance
$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq $roleName}
# If role instance does not exist, instantiate it based on the role template
if (!($role)) {
# Instantiate an instance of the role template
$roleTemplate = Get-AzureADDirectoryRoleTemplate | Where-Object {$_.displayName -eq $roleName}
Enable-AzureADDirectoryRole -RoleTemplateId $roleTemplate.ObjectId
# Fetch role instance again
$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq $roleName}
}
# Add user to role
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $roleMember.ObjectId
# Fetch role membership for role to confirm
Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId | Get-AzureADUser

View File

@@ -0,0 +1,45 @@
# Bulk add a new licence to users on the basis of what licence they currently have.
#
# An updated version of my previous MSOL script, now using AzureAD.
# This is useful for something like adding Office 365 ATP to everyone who currently has E3, for example.
#
# List of available SKUs can be obtained with (Get-AzureADSubscribedSku).SkuPartNumber
#
# What licence do the users currently have?
$existingLicence = 'ENTERPRISEPACK'
# What licence are we adding?
$licenceToAdd = 'ATP_ENTERPRISE'
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Get all available licence skus
$allSkus = Get-AzureADSubscribedSku
# Get sku ID for existing licence
$existingSkuID = ($allSkus | Where-Object {$_.SkuPartNumber -eq $existingLicence}).SkuId
# Get sku ID for new licence
$newSkuID = ($allSkus | Where-Object {$_.SkuPartNumber -eq $licenceToAdd}).SkuId
# Find everyone who has the existing licence but not the licence we're adding
$users = Get-AzureADUser -All $true | Where-Object {$_.AssignedLicenses.SkuId -match $existingSkuID -and !($_.AssignedLicenses.SkuId -match $newSkuID)}
# Create a new licence object for the licence we're adding
$newLicense = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$newLicense.SkuId = $newSkuID
# Create a new assigned licenses object and add the licence we're adding to add licenses
$newLicenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
$newLicenses.AddLicenses = $newLicense
# Add the new licence to each user in the list
foreach ($user in $users) {
Set-AzureADUserLicense -ObjectId $user.UserPrincipalName -AssignedLicenses $newLicenses
}
# Disconnect from AzureAD
Disconnect-AzureAD

View File

@@ -0,0 +1,53 @@
# Bulk add additional licences to a list of users.
#
# An updated version of my previous MSOL script, now using AzureAD.
#
# List of available SKUs can be obtained with (Get-AzureADSubscribedSku).SkuPartNumber
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# What licences are we adding?
$licencesToAdd = @('ENTERPRISEPACK','ATP_ENTERPRISE','EMSPREMIUM')
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Import list of users from file
$userList = Get-Content -Path $userListPath | Sort-Object
# Get all available licence skus
$newSkuIDs = (Get-AzureADSubscribedSku | Where-Object {$_.SkuPartNumber -in $licencesToAdd}).SkuId
# Create a licenses object
$licenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
# Add the licences to add to the licences object
foreach ($newSkuID in $newSkuIDs) {
$newLicense = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$newLicense.SkuId = $newSkuID
$licenses.AddLicenses += $newLicense
}
# Add the licenses
foreach ($username in $userList) {
try {
$user = Get-AzureADUser -ObjectId $username -ErrorAction Stop
if ($user.AccountEnabled -eq $true) {
Set-AzureADUserLicense -ObjectId $user.UserPrincipalName -AssignedLicenses $licenses -ErrorAction Stop
Write-Output -InputObject ('Licence(s) added for user account ' + $user.UserPrincipalName + '.')
}
else {
Write-Output -InputObject ('User account ' + $user.UserPrincipalName + ' is disabled.')
}
}
catch {
Write-Output -InputObject ('There was a problem updating licences for user account ' + $user.UserPrincipalName + '.')
Write-Output -InputObject $Error[0]
}
}
# Disconnect from AzureAD
Disconnect-AzureAD

View File

@@ -0,0 +1,58 @@
# Script to add multiple users to multiple AzureAD roles
<#
You can find a list of available roles in the following Microsoft article
https://docs.microsoft.com/en-us/azure/active-directory/active-directory-assign-admin-roles-azure-portal
Double check using Get-AzureADDirectoryRole as they don't always have the same name in PowerShell as the GUI
Built from the code example on the following Mircosoft page
https://docs.microsoft.com/en-us/powershell/module/azuread/add-azureaddirectoryrolemember?view=azureadps-2.0
#>
# User UPNs to assign roles to
$roleUsers = @('')
# Role Names to Assign
$roleNames = @('')
# Import AzureAD module and Connect
Import-Module AzureAD
Connect-AzureAD
# Run through the list of users
foreach ($roleUser in $roleUsers) {
# Fetch user to assign to role
$roleMember = Get-AzureADUser -ObjectId $roleUser
# Run through the list of roles
foreach ($roleName in $roleNames) {
# Fetch User Account Administrator role instance
$role = Get-AzureADDirectoryRole | Where-Object { $_.displayName -eq $roleName }
# If role instance does not exist, instantiate it based on the role template
if (!($role)) {
# Instantiate an instance of the role template
$roleTemplate = Get-AzureADDirectoryRoleTemplate | Where-Object { $_.displayName -eq $roleName }
Enable-AzureADDirectoryRole -RoleTemplateId $roleTemplate.ObjectId
# Fetch User Account Administrator role instance again
$role = Get-AzureADDirectoryRole | Where-Object { $_.displayName -eq $roleName }
}
# Get existing users with the role assigned
$existingRoleUsers = (Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId).UserPrincipalName
# Assign role to new user if not already in the list
if ($roleMember.UserPrincipalName -notin $existingRoleUsers) {
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $roleMember.ObjectId -ErrorAction Stop
}
}
}
# Uncomment to fetch role membership for each role to confirm
#foreach ($roleName in $roleNames) {
# Write-Output -InputObject ('Members for role: ' + $roleName)
# Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId | Get-AzureADUser | Where-Object {$_.UserPrincipalName -in $roleUsers} | Format-List -Property DisplayName,UserPrincipalName
#}

View File

@@ -0,0 +1,29 @@
# Script to bulk disable guest accounts in Azure AD, either all or for a specific domain
#
# Are we disabling for a specific guest domain? Leave blank for all guests.
$guestDomain = ''
# Install the AzureAD module, uncomment if required
#Install-Module -Name AzureAD
# Import the AzureAD module and connect to Azure AD
Import-Module -Name AzureAD
Connect-AzureAD
# Get a list of all guests from Azure AD either matching the domain or all guests
if ($guestDomain -ne '') {
$guestAccounts = Get-AzureADUser -All $true | Where-Object { $_.AccountEnabled -eq $true -and $_.UserType -eq 'Guest' -and $_.Mail -like ('*' + $guestDomain) }
}
else {
$guestAccounts = Get-AzureADUser -All $true | Where-Object { $_.AccountEnabled -eq $true -and $_.UserType -eq 'Guest' }
}
# Disable the guest accounts
try {
$guestAccounts | Set-AzureADUser -AccountEnabled $false -ErrorAction Stop
Write-Output -InputObject ('The specified guest accounts have been disabled.')
}
catch {
Write-Output -InputObject ('Failed - The specified guest accounts have not been disabled.')
}

View File

@@ -0,0 +1,24 @@
# Script to bulk enable guest accounts in Azure AD, either all or for a specific domain
#
# Are we disabling for a specific guest domain? Leave blank for all guests.
$guestDomain = ''
# Install the AzureAD module, uncomment if required
#Install-Module -Name AzureAD
# Import the AzureAD module and connect to Azure AD
Import-Module -Name AzureAD
Connect-AzureAD
# Get a list of all guests from Azure AD either matching the domain or all guests
if ($guestDomain -ne '') {
$guestAccounts = Get-AzureADUser -All $true | Where-Object { $_.AccountEnabled -eq $false -and $_.UserType -eq 'Guest' -and $_.Mail -like ('*' + $guestDomain) }
}
else {
$guestAccounts = Get-AzureADUser -All $true | Where-Object { $_.AccountEnabled -eq $false -and $_.UserType -eq 'Guest' }
}
# Enable the guest accounts
$guestAccounts | Set-AzureADUser -AccountEnabled $true
Write-Output -InputObject ('The specified guest accounts have been disabled.')

View File

@@ -0,0 +1,21 @@
# Find all guests with unaccepted invites over a specific time period and remove them
#
# How many days are we allowing for invites to be accepted? (This can be 0 for all)
$cutOffDays = 30
# Install the AzureAD module, uncomment if required
#Install-Module -Name AzureAD
# Import the AzureAD module and connect to Azure AD
Import-Module -Name AzureAD
Connect-AzureAD
# Get the cut off date
$cutOffDate = (Get-Date).AddDays(-$cutOffDays)
# Get a list of all guests with unaccepted invites older than the specificed timeframe
$unacceptedGuests = Get-AzureADUser -All $true | Where-Object { $_.UserType -eq 'Guest' -and $_.UserState -eq 'PendingAcceptance' -and $_.RefreshTokensValidFromDateTime -lt $cutOffDate }
# Remove the guest accounts
$unacceptedGuests | Remove-AzureADUser

View File

@@ -0,0 +1,44 @@
# Bulk remove licences to a list of users.
#
# List of available SKUs can be obtained with (Get-AzureADSubscribedSku).SkuPartNumber
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# What licences are we removing?
$licencesToRemove = @('ENTERPRISEPACK','ATP_ENTERPRISE','EMSPREMIUM')
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Import list of users from file
$userList = Get-Content -Path $userListPath | Sort-Object
# Create a licenses object
$licenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
# Get SkuIDs for licence(s) to be removed
$licenses.RemoveLicenses = (Get-AzureADSubscribedSku | Where-Object {$_.SkuPartNumber -in $licencesToRemove}).SkuId
# Remove the licenses
foreach ($username in $userList) {
try {
$user = Get-AzureADUser -ObjectId $username -ErrorAction Stop
if ($user.AccountEnabled -eq $true) {
Set-AzureADUserLicense -ObjectId $user.UserPrincipalName -AssignedLicenses $licenses
Write-Output -InputObject ('Licence(s) removed from user account ' + $user.UserPrincipalName + '.')
}
else {
Write-Output -InputObject ('User account ' + $user.UserPrincipalName + ' is disabled.')
}
}
catch {
Write-Output -InputObject ('There was a problem updating licences for user account ' + $user.UserPrincipalName + '.')
Write-Output -InputObject $Error[0]
}
}
# Disconnect from AzureAD
Disconnect-AzureAD

View File

@@ -0,0 +1,59 @@
# Bulk replace licences to a list of users.
#
# List of available SKUs can be obtained with (Get-AzureADSubscribedSku).SkuPartNumber
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# What licences are we adding?
$licencesToAdd = @('EMSPREMIUM')
# What licences are we removing?
$licencesToRemove = @('EMS','AAD_PREMIUM_P2')
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Import list of users from file
$userList = Get-Content -Path $userListPath | Sort-Object
$userList = @('OAndrewsAdmin@sis.tv')
# Get all available licence skus
$newSkuIDs = (Get-AzureADSubscribedSku | Where-Object {$_.SkuPartNumber -in $licencesToAdd}).SkuId
# Create a licenses object
$licenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
# Add the licences to add to the licences object
foreach ($newSkuID in $newSkuIDs) {
$newLicense = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$newLicense.SkuId = $newSkuID
$licenses.AddLicenses += $newLicense
}
# Add the licences we want to remove to the $licenses object
$licenses.RemoveLicenses = (Get-AzureADSubscribedSku | Where-Object {$_.SkuPartNumber -in $licencesToRemove}).SkuID
# Replace the licenses
foreach ($username in $userList) {
try {
$user = Get-AzureADUser -ObjectId $username -ErrorAction Stop
if ($user.AccountEnabled -eq $true) {
Set-AzureADUserLicense -ObjectId $user.UserPrincipalName -AssignedLicenses $licenses
Write-Output -InputObject ('Licences updated for user account ' + $user.UserPrincipalName + '.')
}
else {
Write-Output -InputObject ('User account ' + $user.UserPrincipalName + ' is disabled.')
}
}
catch {
Write-Output -InputObject ('There was a problem updating licences for user account ' + $user.UserPrincipalName + '.')
Write-Output -InputObject $Error[0]
}
}
# Disconnect from AzureAD
Disconnect-AzureAD

View File

@@ -0,0 +1,14 @@
# Update Online User UPN - when AD sync doesn't do it.
# Import the Azure AD module and connect
Import-Module AzureAD
Connect-AzureAD
# Whose UPN are we changing?
$oldUPN = Read-Host -Prompt 'Enter user''s old UPN in the format username@domain'
# What are we changing it to?
$newUPN = Read-Host -Prompt 'Enter user''s new UPN in the format username@domain'
# Update the UPN in AzureAD
Set-AzureADUser -ObjectId $oldUPN -UserPrincipalName $newUPN

View File

@@ -0,0 +1,10 @@
# Import the Azure AD module and connect
Import-Module AzureAD
Connect-AzureAD
# Whose ID are we getting?
$userUPN = Read-Host -Prompt 'Enter user''s UPN in the format username@domain'
# Convert 365 ImmutableID to AD GUID
$immutableID = (Get-AzureADUser -ObjectId $userUPN).ImmutableID
[GUID][System.Convert]::FromBase64String($immutableID)

View File

@@ -0,0 +1,29 @@
# Retrieve licences for all users and export to CSV.
#
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Get all available licence details
$allSkus = Get-AzureADSubscribedSku
# Import list of users from file
$users = Get-AzureADUser -All $true
# Get Licences for each user and find out what they are from the list
$allUserLicences = @()
foreach ($user in $users) {
$assignedLicences = @()
foreach ($license in $user.AssignedLicenses.SkuID) {
$assignedLicences += ($allSkus | Where-Object { $_.SkuID -eq $license }).SkuPartNumber
}
$userLicences = [PSCustomObject]@{
'UserName' = $user.UserPrincipalName
'AssignedLicences' = (($assignedLicences | Sort-Object) -join ';')
}
$allUserLicences += $userLicences
}
# Export list to CSV file
$allUserLicences | Export-Csv -Path 'C:\Temp\AllUserLicences.csv' -NoTypeInformation

View File

@@ -0,0 +1,38 @@
# Retrieve licences for a list of users and export them to a CSV file.
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Get all available licence details
$allSkus = Get-AzureADSubscribedSku
# Import list of users from file
$users = Get-Content -Path $userListPath | Sort-Object
# Get Licences for user and find out what they are from the list
$allUserLicences = @()
foreach ($user in $users) {
$assignedLicences = @()
try {
$userDetails = Get-AzureADUser -ObjectId $user -ErrorAction Stop
foreach ($license in $userDetails.AssignedLicenses.SkuID) {
$assignedLicences += ($allSkus | Where-Object { $_.SkuID -eq $license }).SkuPartNumber
}
}
catch {
$assignedLicences = 'User not found.'
}
$userLicences = [PSCustomObject]@{
'UserName' = $user
'AssignedLicences' = (($assignedLicences | Sort-Object) -join ';')
}
$allUserLicences += $userLicences
}
# Export list to CSV file
$allUserLicences | Export-Csv -Path 'C:\Temp\UserLicences.csv' -NoTypeInformation

View File

@@ -0,0 +1,84 @@
# Some example scripts for finding users with specific plans assigned
#
# A full list of subscription and plan ID's is available from:
# https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/licensing-service-plan-reference
#
# Here I'm using the following plan IDs.
#
# OFFICESUBSCRIPTION (43de0ff5-c92c-492b-9116-175376d08c38)
# PROJECT_CLIENT_SUBSCRIPTION (fafd7243-e5c1-4a3a-9e40-495efcb1d3c3)
# VISIO_CLIENT_SUBSCRIPTION (663a804f-1c30-4ff0-9915-9db84f0d1cea)
#
# Plan ID's to check for
$planID1 = '43de0ff5-c92c-492b-9116-175376d08c38'
$planID2 = 'fafd7243-e5c1-4a3a-9e40-495efcb1d3c3'
$planID3 = '663a804f-1c30-4ff0-9915-9db84f0d1cea'
# Import the AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Get all users from AzureAD
$allUsers = Get-AzureADUser -All $true
# Create variables to put the users in to
$planID1Users = @()
$planID2Users = @()
$planID3Users = @()
# Check through the users and check what plans are assigned and enabled
foreach ($user in $allUsers) {
foreach ($assignedPlan in $user.AssignedPlans) {
# Find all users of plan 1 and add to the related variable
if ($assignedPlan.ServicePlanId -eq $planID1 -and $assignedPlan.CapabilityStatus -eq 'Enabled') {
$planID1Users += $user
}
# Find all users of plan 2 and add to the related variable
if ($assignedPlan.ServicePlanId -eq $planID2 -and $assignedPlan.CapabilityStatus -eq 'Enabled') {
$planID2Users += $user
}
# Find all users of plan 3 and add to the related variable
if ($assignedPlan.ServicePlanId -eq $planID3 -and $assignedPlan.CapabilityStatus -eq 'Enabled') {
$planID3Users += $user
}
}
}
# Create variables to put the users in to
$plan1OnlyUsers = @()
$planID1and2Users = @()
$planID1and3Users = @()
$planID12and3Users = @()
# Using plan 1 as the master list, check which other licences are assigned
foreach ($planID1User in $planID1Users) {
# Find users who are only in the plan 1 list
if ($planID1User -notin $planID2Users -and $planID1User -notin $planID3Users) {
$plan1OnlyUsers += $planID1User
}
# Find users who are the plan 1 and plan 2 list
if ($planID1User -in $planID2Users) {
$planID1and2Users += $planID1User
}
# Find users who are in the plan 1 and plan 3 list
if ($planID1User -in $planID3Users) {
$planID1and3Users += $planID1User
}
# Find users who are in all three lists
if ($planID1User -in $planID2Users -and $planID1User -in $planID3Users) {
$planID12and3Users += $planID1User
}
}
# How many people in each list?
$plan1OnlyUsers.Count
$planID1and2Users.Count
$planID1and3Users.Count
$planID12and3Users.Count
# Who are those people?
$plan1OnlyUsers
$planID1and2Users
$planID1and3Users
$planID12and3Users

View File

@@ -0,0 +1,36 @@
# Script to invite a list of guest users to AzureAD and add them to a group
#
# Useful for bulk adding guests to a SharePoint or Teams group
#
# Uses a CSV file containing columns for FirstName,LastName,DisplayName,ExternalEmailAddress
#
# Where is our list of people?
$contactsFile = 'C:\Temp\ExternalContacts.csv'
# What group are we added them to?
$groupName = 'Test Group'
# Import the AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Import the list of people
$contactsList = Import-Csv -Path $contactsFile
# Find the group ID for our group
$groupID = (Get-AzureADGroup -All $true | Where-Object {$_.DisplayName -eq $groupName}).ObjectId
# Run through the list sending the guest invite and adding them to the group, unless their email address is already used somewhere
foreach ($externalUser in $contactsList) {
$getExisting = Get-AzureADUser -SearchString $externalUser.ExternalEmailAddress
if ($getExisting.Count -eq 0) {
$newUser = New-AzureADMSInvitation -InvitedUserDisplayName $externalUser.DisplayName -InvitedUserEmailAddress $externalUser.ExternalEmailAddress -SendInvitationMessage $true -InviteRedirectUrl "https://myapps.microsoft.com"
Add-AzureADGroupMember -ObjectId $groupID -RefObjectId $newUser.InvitedUser.Id
Write-Output -InputObject ('Guest ' + $externalUser.ExternalEmailAddress + ' created and added to group.')
}
else {
Write-Output -InputObject ('Object already exists with email address ' + $externalUser.ExternalEmailAddress + '.')
}
}

View File

@@ -0,0 +1,42 @@
# Remove all licences from a list of users
#
# Removing licences with this module doesn't work in the way that Microsoft's documentation states.
# I'm assuming this is a bug, so the code below works at time of creation but may stop working in the future.
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# Import AzureAD module and connect
Import-Module AzureAD
Connect-AzureAD
# Import list of users from file
$userList = Get-Content -Path $userListPath | Sort-Object
# Remove all the licences
foreach ($username in $userList) {
try {
$user = Get-AzureADUser -ObjectId $username -ErrorAction Stop
if ($user.AccountEnabled -eq $true) {
if(($user.AssignedLicenses.SkuId).Count -ge 1) {
$licenses = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
$licenses.RemoveLicenses = (Get-AzureADSubscribedSku | Where-Object {$_.SkuId -in $user.AssignedLicenses.SkuId}).SkuId
Set-AzureADUserLicense -ObjectId $user.UserPrincipalName -AssignedLicenses $licenses
Write-Output -InputObject ('All licences removed from user account ' + $username + '.')
}
else {
Write-Output -InputObject ('User account ' + $username + ' has no licences assigned.')
}
}
else {
Write-Output -InputObject ('User account ' + $username + ' is disabled.')
}
}
catch {
Write-Output -InputObject ('User account ' + $username + ' does not exist.')
}
}
# Disconnect from AzureAD
Disconnect-AzureAD

View File

@@ -0,0 +1,63 @@
# Script to get details for a list of mailboxes and save that out to a CSV file
#
# File containing the list of mailboxes
$inputFile = 'C:\Temp\MailboxList.txt'
# File to save the results to
$outputFile = 'C:\Temp\SharedMailboxes.csv'
# Establish a session to Exchange Online
$credentials = Get-Credential -Message 'Enter your Exchange Online administrator credentials'
$connectionParams = @{
'ConfigurationName' = 'Microsoft.Exchange';
'ConnectionUri' = 'https://outlook.office365.com/powershell-liveid/';
'Credential' = $credentials;
'Authentication' = 'Basic';
'AllowRedirection' = $true
}
$exchangeSession = New-PSSession @connectionParams
Import-PSSession -Session $exchangeSession
# Check output folder exists and create it if it doesn't
$outputPath = (Split-Path -Path $outputFile)
if (!(Test-Path -Path $outputPath)) {New-Item -Path $outputFolder -ItemType Directory}
# If output file already exists, delete it.
if (Test-Path -Path $outputFile) {Remove-Item -Path $outputFile}
# Get the list of mailboxes from the file
$mailboxes = Get-Content -Path $inputFile
# Initialise the results table
$mailboxesTable = @()
# Iterate through the mailboxes from the file and show a progress bar as we go.
foreach ($mailbox in $mailboxes) {
Write-Progress -Activity 'Checking..' -status $mailbox -percentComplete ($mailboxes.IndexOf($mailbox) / $mailboxes.Count * 100)
# Get the statistics for the mailbox.
$mailboxStats = ''
$mailboxStats = Get-MailboxStatistics -Identity $mailbox -ErrorAction SilentlyContinue -
# If mailboxStats is blank then mailbox doesn't exist, so that entry can be skipped. For all others get the mailbox permissions and build the output table.
if ($mailboxStats -ne $null) {
# Get permit permissions for users where the username has an @ in it, this filters out all the system permissions.
$usersWithAccess = (Get-MailboxPermission -Identity $mailbox | Where-Object -Property {($_.User -like '*@*') -and ($_.Deny -ne 'False')}).User -join '; '
$tableRow = New-Object System.Object
$tableRow | Add-Member -MemberType NoteProperty -Name 'MailboxUPN' -Value $mailbox
$tableRow | Add-Member -MemberType NoteProperty -Name 'MailboxType' -Value $mailboxStats.MailboxTypeDetail
$tableRow | Add-Member -MemberType NoteProperty -Name 'ItemCount' -Value $mailboxStats.ItemCount
$tableRow | Add-Member -MemberType NoteProperty -Name 'TotalItemSize' -Value $mailboxStats.TotalItemSize
$tableRow | Add-Member -MemberType NoteProperty -Name 'LastLogonTime' -Value $mailboxStats.LastLogonTime
$tableRow | Add-Member -MemberType NoteProperty -Name 'UsersWithAccess' -Value $usersWithAccess
$mailboxesTable += $tableRow
}
}
# Output the final table of results to a file.
$mailboxesTable | Export-Csv -Path $outputFile -NoTypeInformation
# End the Exchange Online session
Remove-PSSession -Session $exchangeSession

View File

@@ -0,0 +1,20 @@
# Find mailboxes where UPN domain doesn't match email domain
#
# Establish a session to Exchange Online
$credentials = Get-Credential -Message 'Enter your Exchange Online administrator credentials'
$connectionParams = @{
'ConfigurationName' = 'Microsoft.Exchange';
'ConnectionUri' = 'https://outlook.office365.com/powershell-liveid/';
'Credential' = $credentials;
'Authentication' = 'Basic';
'AllowRedirection' = $true
}
$exchangeSession = New-PSSession @connectionParams
Import-PSSession -Session $exchangeSession
# Get list of mailboxes with a different mail domain to UPN domain
Get-Mailbox -ResultSize Unlimited | Where-Object {$_.UserPrincipalName.Split('@')[1] -ne $_.PrimarySmtpAddress.Split('@')[1]} | Format-Table Name,UserPrincipalName,PrimarySmtpAddress,RecipientTypeDetails
# Disconnect from Exchange Online
Remove-PSSession $exchangeSession

View File

@@ -0,0 +1,38 @@
# Script to get all client forwarding rules, smtp forwarding rules and delegates on mailboxes
#
# This builds on top of a script from https://github.com/OfficeDev/O365-InvestigationTooling
#
# Establish a session to Exchange Online
$credentials = Get-Credential -Message 'Enter your Exchange Online administrator credentials'
$connectionParams = @{
'ConfigurationName' = 'Microsoft.Exchange';
'ConnectionUri' = 'https://outlook.office365.com/powershell-liveid/';
'Credential' = $credentials;
'Authentication' = 'Basic';
'AllowRedirection' = $true
}
$exchangeSession = New-PSSession @connectionParams
Import-PSSession -Session $exchangeSession
$allUsers = @()
$allUsers = Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName,UserPrincipalName,ForwardingAddress,ForwardingSMTPAddress,DeliverToMailboxandForward
$userInboxRules = @()
$userDelegates = @()
foreach ($user in $allUsers) {
Write-Progress -Activity "Checking inbox rules for..." -status $user.UserPrincipalName -percentComplete ($allUsers.IndexOf($user) / $allUsers.Count * 100)
$userInboxRules += Get-InboxRule -Mailbox $user.UserPrincipalName | `
Select-Object MailboxOwnerId,Name,Description,Enabled,Priority,ForwardTo,ForwardAsAttachmentTo,RedirectTo,DeleteMessage | `
Where-Object {($_.ForwardTo -ne $null) -or ($_.ForwardAsAttachmentTo -ne $null) -or ($_.RedirectsTo -ne $null)}
$userDelegates += Get-MailboxPermission -Identity $user.UserPrincipalName | Where-Object {($_.IsInherited -ne "True") -and ($_.User -notlike "*SELF*")}
}
$smtpForwarding = $allUsers | Select-Object DisplayName,ForwardingAddress,ForwardingSMTPAddress,DeliverToMailboxandForward | Where-Object {$_.ForwardingSMTPAddress -ne $null}
$userInboxRules | Export-Csv MailForwardingRulesToExternalDomains.csv -NoTypeInformation
$smtpForwarding | Export-Csv Mailboxsmtpforwarding.csv -NoTypeInformation
$userDelegates | Export-Csv MailboxDelegatePermissions.csv -NoTypeInformation
Remove-PSSession -Session $exchangeSession

View File

@@ -0,0 +1,41 @@
# Script to grant access rights on mailboxes
#
# Mailboxes to grant rights on
$grantRightsOnMailboxes = @('','')
# Users to grant rights to
$grantRightsToUsers = @('','')
# Rights to grant
$accessRights = 'Editor'
# Establish a session to Exchange Online
$credentials = Get-Credential -Message 'Enter your Exchange Online administrator credentials'
$connectionParams = @{
'ConfigurationName' = 'Microsoft.Exchange';
'ConnectionUri' = 'https://outlook.office365.com/powershell-liveid/';
'Credential' = $credentials;
'Authentication' = 'Basic';
'AllowRedirection' = $true
}
$exchangeSession = New-PSSession @connectionParams
Import-PSSession -Session $exchangeSession
# Apply the permissions
foreach ($grantRightsToUser in $grantRightsToUsers ) {
foreach ($grantRightsOnMailbox in $grantRightsOnMailboxes) {
$calendarIdentity = $grantRightsOnMailbox + ':\Calendar'
$existingPermissions = Get-MailboxFolderPermission -Identity $calendarIdentity -User $grantRightsToUser -ErrorAction SilentlyContinue
if (!($existingPermissions)) {
Add-MailboxFolderPermission -Identity $calendarIdentity -User $grantRightsToUser -AccessRights $accessRights
}
else {
Set-MailboxFolderPermission -Identity $calendarIdentity -User $grantRightsToUser -AccessRights $accessRights
}
Set-Mailbox -Identity $upn GrantSendOnBehalfTo @{add=$editor}
}
}
# End the PowerShell session
Remove-PSSession -Session $exchangeSession

View File

@@ -0,0 +1,45 @@
# Enable mailbox auditing and disable PowerShell remoting on individual mailboxes
#
# Working on this as a one stop for hardening Exchange Online accounts
#
# UPN of New User
$newUPN = ''
# Is the user an administrator?
$isAnAdmin = $false
# Establish a session to Exchange Online
$credentials = Get-Credential -Message 'Enter your Exchange Online administrator credentials'
$connectionParams = @{
'ConfigurationName' = 'Microsoft.Exchange';
'ConnectionUri' = 'https://outlook.office365.com/powershell-liveid/';
'Credential' = $credentials;
'Authentication' = 'Basic';
'AllowRedirection' = $true
}
$exchangeSession = New-PSSession @connectionParams
Import-PSSession -Session $exchangeSession
# Set Auditing parameters
$params = @{
'AuditEnabled' = $true
'AuditLogAgeLimit' = '180'
'AuditAdmin' = @('Update','MoveToDeletedItems','SoftDelete','HardDelete','SendAs','SendOnBehalf','Create','UpdateFolderPermission')
'AuditDelegate' = @('Update','SoftDelete','HardDelete','SendAs','Create','UpdateFolderPermissions','MoveToDeletedItems','SendOnBehalf')
'AuditOwner' = @('UpdateFolderPermission','MailboxLogin','Create','SoftDelete','HardDelete','Update','MoveToDeletedItems')
}
# Enable Auditing
Get-Mailbox -Identity $newUPN | Set-Mailbox @params
# Disable PowerShell Remoting for non-Admin staff
if ($isAnAdmin) {
Set-User -Identity $newUPN -RemotePowerShellEnabled $true
}
else {
Set-User -Identity $newUPN -RemotePowerShellEnabled $false
}
# Disconnect from Exchange Online
Remove-PSSession $exchangeSession

View File

@@ -0,0 +1,111 @@
# Script to bulk remove email proxy addresses from Exchange users in a synced environment using an on-prem Exchange management server
#
# What is the FQDN of the on-prem Exchange server?
$exchangeServerFQDN = ''
# Which domains are we removing?
$domainsToRemove = @('','')
# Create Exchange connection Uri from FQDN
$exchangeConnectionUri = 'http://' + $exchangeServerFQDN +'/PowerShell/'
# Establish a session to Exchange
$userCredential = Get-Credential
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $exchangeConnectionUri -Authentication Kerberos -Credential $userCredential
Import-PSSession $session -DisableNameChecking
### Check if address policies are using this domain ###
# Initialise a hastable to store our results in
$addressPolicies = @()
# Get all address policies from Exchange
$allAddressPolicies = Get-EmailAddressPolicy
# Run through the domains checking if the domain to be removed is in the address policies
foreach ($domainToRemove in $domainsToRemove) {
$emailAddressTemplate = 'SMTP:@' + $domainToRemove
$addressPolicies += $allAddressPolicies | Where-Object {$_.EnabledEmailAddressTemplates -contains $emailAddressTemplate}
}
# If domain found in address policies then list them and ask if we want to contiue removing the proxy domain
if ($addressPolicies.Count -gt 0) {
Write-Output -InputObject ('The following address policies are using the domain to be removed:')
$addressPolicies | Format-Table
$continue = ''
while ($continue -notmatch '[YyNn]') {
$continue = Read-Host -Prompt 'Do you want to continue running the script? (Y/N)'
}
if ($continue -match '[Nn]') {
Write-Output -InputObject ('Terminating script.')
break
}
else {
Write-Output -InputObject ('Continuing with script.')
}
}
###
### Remove the domain from mailboxes ###
# Get All Mailboxes
$allMailboxes = Get-RemoteMailbox -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each mailbox
foreach ($mailbox in $allMailboxes) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($mailbox.EmailAddresses -split ',' | Where-Object {$_ -match $domainToRemove}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from maibox ' + $mailbox.Name)
Set-RemoteMailbox -Identity $mailbox.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false
}
}
###
### Remove the domain from contacts ###
# Get all the contacts
$allContacts = Get-MailContact -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each contact
foreach ($contact in $allContacts) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($contact.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from contact ' + $contact.Name)
Set-MailContact -Identity $contact.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false -ForceUpgrade:$true
}
}
###
### Remove the domain from groups ###
# Get all the groups (this includes email enabled security groups)
$allGroups = Get-DistributionGroup -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each group
foreach ($group in $allGroups) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($group.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from group ' + $group.Name)
Set-DistributionGroup -Identity $group.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false
}
}
###
### Public folders don't feature here because in this scenario they're cloud only ###
# End the Exchange Session
Remove-PSSession -Session $session

View File

@@ -0,0 +1,62 @@
# Find mailboxes for synced accounts, where the mailbox exists in Exchange Online but doesn't exist on-prem as a remote mailbox.
#
# Like the other stuff in this folder, it's a bit of a niche scenario.
# We're looking for mailboxes which were created in on-prem AD and then licenced in the cloud without a remote mailbox being created on the on-prem Exchange server, so that we can remote mail enable them correctly.
#
# This is a bit complicated as it requires connected to two Exchange environments at once, so uses command prefixes for one of them.
#
# What is the FQDN of the on-prem Exchange server?
$exchangeServerFQDN = ''
# What is your remote routing address? E.g.: @domain.mail.onmicrosoft.com
$remoteRoutingSuffix = '@domain.mail.onmicrosoft.com'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Create Exchange on-prem connection Uri from FQDN
$exchangeConnectionUri = 'http://' + $exchangeServerFQDN +'/PowerShell/'
# Establish a session to Exchange on-prem and add the OnPrem prefix to all commands
$userCredential = Get-Credential
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $exchangeConnectionUri -Authentication Kerberos -Credential $userCredential
Import-PSSession $session -DisableNameChecking -Prefix OnPrem
# Get list of mailboxes from Exchange online for synced users
$allOnlineMailboxes = Get-Mailbox -ResultSize Unlimited | Where-Object {$_.IsDirSynced -eq $true -and $_.Name -notlike 'DiscoverySearchMailbox*'}
# Get list of remote mailboxes from on-prem server
$allOnPremMailboxes = Get-OnPremRemoteMailbox -ResultSize Unlimited
# Compare the two lists and add those missing from the on-prem list to the $syncedMailboxMismatch hashtable
$syncedMailboxMismatch = $allOnlineMailboxes | Where-Object {$allOnPremMailboxes.PrimarySmtpAddress -notcontains $_.PrimarySmtpAddress}
# Find mailboxes where alias and username match
$matchedUPNAliases = $syncedMailboxMismatch | Where-Object {$_.Alias -eq $_.UserPrincipalName.Split('@')[0]}
# Find mailboxes where alias and username don't match
$mismatchedUPNAliases = $syncedMailboxMismatch | Where-Object {$_.Alias -ne $_.UserPrincipalName.Split('@')[0]}
# Fix the mailboxes where username and alias matched.
foreach ($mailboxToRemoteEnable in $matchedUPNAliases) {
$mailboxUsername = $mailboxToRemoteEnable.UserPrincipalName.Split('@')[0]
$mailboxToFix = $mailboxToRemoteEnable.UserPrincipalName
$remoteRoutingAddress = $mailboxUsername + $remoteRoutingSuffix
Enable-OnPremRemoteMailbox -Identity $mailboxToFix -RemoteRoutingAddress $remoteRoutingAddress
}
# Write out the mailboxes that have been updated
Write-Output -InputObject ('The following mailboxes have been remote mail enabled.')
$matchedUPNAliases | Select-Object Name,Alias,UserPrincipalName,PrimarySmtpAddress
# Write out the mailboxes that have been left due to a mismatch between username and alias
Write-Output -InputObject ('The following mailboxes have not been changed because they have a mismatch between email alias and username.')
$mismatchedUPNAliases | Select-Object Name,Alias,UserPrincipalName,PrimarySmtpAddress
# End the Exchange Session
Remove-PSSession -Session $session

View File

@@ -0,0 +1,24 @@
# Disable a list of mail users
#
# What is the FQDN of the on-prem Exchange server?
$exchangeServerFQDN = ''
# What accounts are we disabling?
$usersToDisable = @('','')
# Create Exchange connection Uri from FQDN
$exchangeConnectionUri = 'http://' + $exchangeServerFQDN +'/PowerShell/'
# Establish a session to Exchange
$userCredential = Get-Credential
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $exchangeConnectionUri -Authentication Kerberos -Credential $userCredential
Import-PSSession $session -DisableNameChecking -AllowClobber
# Get list of mailboxes
foreach ($userToDisable in $usersToDisable) {
Disable-RemoteMailbox -Identity $userToDisable -Confirm:$false
}
# End the Exchange Session
Remove-PSSession -Session $session

View File

@@ -0,0 +1,28 @@
# Find mailboxes using a specific email domain and export list to CSV file
#
# What is the FQDN of the on-prem Exchange server?
$exchangeServerFQDN = ''
# Primary SMTP domain to search for
$primarySMTP = ''
# Where are we saving the output file?
$outputFile = 'C:\Temp\Mailboxes.csv'
# Create Exchange connection Uri from FQDN
$exchangeConnectionUri = 'http://' + $exchangeServerFQDN +'/PowerShell/'
# Establish a session to Exchange
$userCredential = Get-Credential
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $exchangeConnectionUri -Authentication Kerberos -Credential $userCredential
Import-PSSession $session -DisableNameChecking
# Get list of mailboxes
$allMailboxes = Get-RemoteMailbox -ResultSize Unlimited | Where-Object {($_.PrimarySmtpAddress.Split('@')[1] -eq $primarySMTP)}
# Export results to CSV file
$allMailboxes | Select-Object Name,Alias,UserPrincipalName,PrimarySmtpAddress,EmailAddresses | Export-Csv -Path $outputFile -NoTypeInformation
# End the Exchange Session
Remove-PSSession -Session $session

View File

@@ -0,0 +1,15 @@
# Exchange Online with AzureAD Connect
## What is this?
The scripts in this folder are for managing mailboxes in a synced environment, where you have an Exchange server on-prem purely for management purposes. This means all mailboxes are seen as "remote" mailboxes, so all the scripts use commands to that effect. These can easily be updated to a normal environment like on-prem only or cloud only just by removing the work "remote" from the commands. For example, Get-RemoteMailbox to just Get-Mailbox.
## Pre-requisites
These scripts require you to have on-prem Active Directory with an on-prem Exchange server for management, and using AzureAD Connect to sync to AzureAD.
It's pretty niche.
## Disclaimer
All scripts are provided as is without warranty of any kind, use them at your own risk.

View File

@@ -0,0 +1,20 @@
# Bulk change guest accounts from a certain domain so that they show in the Global Address List
#
# Uses the new PowerShell "module" that support MFA.
#
# What domain are the guests email addresses from?
$guestDomain = ''
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Find all the relevant users and enable them to show in the address list
Get-MailUser -ResultSize Unlimited | Where-Object {$_.RecipientTypeDetails -eq 'GuestMailUser' -and $_.EmailAddresses -match $guestDomain} | Set-MailUser -HiddenFromAddressListsEnabled $false
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,42 @@
# Create a group and add it to all room mailboxes as an editor
#
# Uses the new PowerShell "module" that support MFA.
#
# What do you want the editors group to be called?
$editorsGroup = 'Calendar Editors'
# Who do you want to be in the group? This can be 1 or more people.
$editorsMembers = @('','')
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get all room mailboxes in the organisation
$roomMailboxes = (Get-Mailbox -RecipientTypeDetails RoomMailbox).Alias
# If the editors group doesn't exist, create it.
if (!(Get-DistributionGroup -Identity $editorsGroup -ErrorAction SilentlyContinue)) {
New-DistributionGroup -Name $editorsGroup -Type Security
}
# Add members to the group
$existingMembers = Get-DistributionGroupMember -Identity $editorsGroup
foreach ($editorsMember in $editorsMembers) {
if ($editorsMember -notin $existingMembers.Name) {
Add-DistributionGroupMember -Identity $editorsGroup -Member $editorsMember
}
}
# Add the permissions to the mailboxes
foreach ($roomMailbox in $roomMailboxes) {
$calendarFolder = $mailboxAlias + ':\calendar'
Add-MailboxFolderPermission -Identity $calendarFolder -User $editorsGroup -AccessRights Editor
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,41 @@
# Create a rule to block email forwarding to specific domains.
#
# Uses the new PowerShell "module" that support MFA.
#
# What domains are we blocking?
$domainListFile = 'C:\Temp\DomainList.txt'
# What do we want to call the rule?
$ruleName = 'Block Auto Forwarding to Specific Domains 4'
# What reason do we want end users to see for the rejection?
$rejectionReason = 'Auto forwarding messages to this email provider is not permitted.'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get the domain list from the file
$domainList = Get-Content -Path $domainListFile
# Create a new rule
$parameters = @{
'Name' = $ruleName;
'FromScope' = 'InOrganization';
'SenderAddressLocation' = 'Header'
'RecipientDomainIs' = $domainList;
'MessageTypeMatches' = 'AutoForward';
'RejectMessageEnhancedStatusCode' = '5.7.1'
'RejectMessageReasonText' = $rejectionReason;
'Priority' = 0;
'Mode' = 'Enforce'
'Enabled' = $true
}
New-TransportRule @parameters
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,91 @@
# Script to bulk remove email proxy addresses from Exchange Online users
#
# Which domains are we removing?
$domainsToRemove = @('','')
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
### Remove the domain from mailboxes ###
# Get All Mailboxes
$allMailboxes = Get-Mailbox -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each mailbox
foreach ($mailbox in $allMailboxes) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($mailbox.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from maibox ' + $mailbox.Name)
Set-Mailbox -Identity $mailbox.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false
}
}
###
### Remove the domain from contacts ###
# Get all the contacts
$allContacts = Get-MailContact -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each contact
foreach ($contact in $allContacts) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($contact.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from contact ' + $contact.Name)
Set-MailContact -Identity $contact.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false -ForceUpgrade:$true
}
}
###
### Remove the domain from groups ###
# Get all the groups (this includes email enabled security groups)
$allGroups = Get-DistributionGroup -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each group
foreach ($group in $allGroups) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($group.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from group ' + $group.Name)
Set-DistributionGroup -Identity $group.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false
}
}
###
### Remove the domain from public folders ###
# Get all the groups (this includes email enabled security groups)
$allPublicFolders = Get-MailPublicFolder -ResultSize Unlimited | Sort-Object -Property alias
# Remove alias from each public folder
foreach ($publicFolder in $allPublicFolders) {
$redundantAddresses = @()
foreach ($domainToRemove in $domainsToRemove) {
$redundantAddresses += (($publicFolder.EmailAddresses -split ',' | Where-Object {$_ -like ('*' + $domainToRemove + '*')}) -replace 'smtp:','')
}
if ($redundantAddresses.Count -gt 0) {
Write-Output -InputObject ('Removing addresses ' + $redundantAddresses + ' from public folder ' + $publicFolder.Name)
Set-MailPublicFolder -Identity $publicFolder.Identity -EmailAddresses @{remove=$redundantAddresses} -Confirm:$false
}
}
###
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,20 @@
# Enable Modern Authentication in Exchange Online
#
# Uses the new PowerShell "module" that support MFA.
#
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Enable modern authentication
Set-OrganizationConfig -OAuth2ClientProfileEnabled $true
# Verify the setting has changed
Get-OrganizationConfig | Format-Table -AutoSize Name,OAuth2ClientProfileEnabled
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,29 @@
# Enable mailbox auditing on mailboxes where auditing is not already enabled
#
# This is a rewrite of a script from https://github.com/OfficeDev/O365-InvestigationTooling
#
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Set Auditing parameters
$params = @{
'AuditEnabled' = $true
'AuditLogAgeLimit' = '180'
'AuditAdmin' = @('Update','MoveToDeletedItems','SoftDelete','HardDelete','SendAs','SendOnBehalf','Create','UpdateFolderPermission')
'AuditDelegate' = @('Update','SoftDelete','HardDelete','SendAs','Create','UpdateFolderPermissions','MoveToDeletedItems','SendOnBehalf')
'AuditOwner' = @('UpdateFolderPermission','MailboxLogin','Create','SoftDelete','HardDelete','Update','MoveToDeletedItems')
}
# Enable Auditing
Get-Mailbox -ResultSize Unlimited | Where-Object {$_.RecipientTypeDetails -match '(User|Shared|Room|Discovery)Mailbox' -and $_.AuditEnabled -eq $false} | Set-Mailbox @params
# Check Auditing
Get-Mailbox -ResultSize Unlimited | Where-Object {$_.RecipientTypeDetails -match '(User|Shared|Room|Discovery)Mailbox'} | Format-Table -AutoSize UserPrincipalName,RecipientTypeDetails,AuditEnabled,AuditLogAgeLimit
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,15 @@
# Find mailboxes where UPN domain doesn't match email domain
#
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get list of mailboxes with a different mail domain to UPN domain
Get-Mailbox -ResultSize Unlimited | Where-Object {$_.UserPrincipalName.Split('@')[1] -ne $_.PrimarySmtpAddress.Split('@')[1]} | Format-Table Name,UserPrincipalName,PrimarySmtpAddress,RecipientTypeDetails
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,40 @@
# Find shared mailboxes on the basis of their email domain and lists of who has access to them
#
# Uses the new PowerShell "module" that support MFA.
#
# Where to save the CSV files to
$outputFile = 'C:\Temp\GroupDetails.csv'
# Wildcard for groups to find
$searchWildcard = '*@example.domain'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get all the groups we're looking for
$allGroups = Get-DistributionGroup | Where-Object {$_.PrimarySmtpAddress -like $searchWildcard}
# Initialise the hash table to store results in
$groupDetails = @()
# Run through the groups getting the members and adding
foreach ($group in $allGroups) {
$groupMembers = (Get-DistributionGroupMember -Identity $group.Name).Alias -join '; '
$groupDetails += [PSCustomObject]@{
'GroupName' = $group.Name;
'GroupEmail' = $group.PrimarySmtpAddress;
'GroupType' = $group.GroupType;
'GroupMembers' = $groupMembers
}
}
# Export results to CSV file
$groupDetails | Export-Csv -Path $outputFile -NoTypeInformation
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,40 @@
# Get the permissions and sendas rights for a list of mailboxes and output them to CSV
#
# Uses the new PowerShell "module" that support MFA.
#
# Where to save the CSV files to
$outputPath = 'C:\Temp\MailboxPermissions\'
# What mailboxes are we checking?
$mailboxes = Get-Content -Path 'C:\Temp\Mailboxes.txt'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get all non-inherited mailbox permissions excluding self and output to a CSV file named for each mailbox
foreach ($mailbox in $mailboxes) {
Write-Output -InputObject ('Getting permissions for mailbox ' + $mailbox)
$mailboxPermissions = Get-MailboxPermission -Identity $mailbox | Where-Object {$_.IsInherited -eq $false -and $_.User -ne 'NT AUTHORITY\SELF'} | Select-Object Identity,User,AccessRights,Deny
if ($mailboxPermissions.Count -gt 0) {
$outputFile = $outputPath + 'MailboxPermissions_' + ($mailbox -replace '@','_') + '.csv'
$mailboxPermissions | Export-CSV -Path $outputFile -NoTypeInformation
}
}
# Get all non-inherited recipient permissions (sendas) excluding self and output to a CSV file named for each mailbox
foreach ($mailbox in $mailboxes) {
Write-Output -InputObject ('Getting permissions for recipient ' + $mailbox)
$recipientPermissions = Get-RecipientPermission -Identity $mailbox | Where-Object {$_.IsInherited -eq $false -and $_.Trustee -ne 'NT AUTHORITY\SELF'} | Select-Object Identity,Trustee,AccessRights,AccessControlType
if ($recipientPermissions.Count -gt 0) {
$outputFile = $outputPath + 'RecipientPermissions_' + ($mailbox -replace '@','_') + '.csv'
$recipientPermissions | Export-CSV -Path $outputFile -NoTypeInformation
}
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,32 @@
# Find shared mailboxes on the basis of their email domain and lists of who has access to them
#
# Uses the new PowerShell "module" that support MFA.
#
# Where to save the CSV files to
$outputPath = 'C:\Temp\'
# Wildcard for mailboxes to find
$searchWildcard = '*'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get all the mailboxes we're looking for
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited | Where-Object {$_.PrimarySmtpAddress -like $searchWildcard} | Select-Object Name,Alias,PrimarySmtpAddress,ProhibitSendQuota
# Export list of mailboxes to CSV File
$sharedMailboxes | Export-CSV -Path ($outputPath + 'Shared Mailboxes.csv') -NoTypeInformation
# Get all non-inherited permissions excluding self and output to a CSV file named for each group
foreach ($sharedMailbox in $sharedMailboxes) {
$mailboxPermissions = Get-MailboxPermission -Identity $sharedMailbox.alias | Where-Object {$_.IsInherited -eq $false -and $_.User -ne 'NT AUTHORITY\SELF'} | Select-Object Identity,User,AccessRights,Deny
$mailboxPermissions | Export-CSV -Path ($outputPath + $sharedMailbox.Name + '.csv') -NoTypeInformation
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,27 @@
# Exchange Online with MFA Support
## What is this?
Connecting to Exchange Online through a remote PowerShell session doesn't work when using multi factor authentication. You can (apparrently) get round that by creating an application password, but I've never got it to work and in my mind creating a password to bypass MFA somewhat defeates the point of enabling MFA in the first place.
There now is a new "module" available which does support MFA, so this folder is where I'll be putting new scripts that support MFA or old scripts as I update them.
## Pre-requisites
To connect using MFA you have to locally install a new module from Microsoft. Which for whatever reason isn't available from PSGallery, nor can it be simply downloaded. Instead it has to be installed from within the Exchange Online admin centre using one of those annoying ClickOnce installers that only work in MS's own web browsers.
Microsoft have a document explaining the unnecessarily convulted install process here:
[Connect to Exchange Online PowerShell using multi-factor authentication](https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps)
In addition, because this will be using a remote session it will require the script execution policy within PowerShell to be changed to RemoteSigned. This is done either globally with:
`Set-ExecutionPolicy -ExecutionPolicy RemoteSigned`
Or for the current user with:
`Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser`
## Disclaimer
All scripts are provided as is without warranty of any kind, use them at your own risk.

View File

@@ -0,0 +1,32 @@
# Reset default calendar permissions to availability for a list of users.
#
# Uses the new PowerShell "module" that support MFA.
#
# File with list of users
$userlistPath = 'C:\Temp\Userlist.txt'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get list of users
$userlist = Get-Content -Path $userlistPath
# Get mailboxes for users in list
$mailboxes = Get-Mailbox -ResultSize Unlimited | Where-Object {$_.Name -in $userlist} | Sort-Object -Property Name
# Check the mailboxes and reset any which have default permissions of None to AvailabilityOnly
foreach ($mailbox in $mailboxes) {
$calendarPath = $mailbox.UserPrincipalName + ':\Calendar'
$defaultPermissions = Get-MailboxFolderPermission -Identity $calendarPath -User 'Default'
if ($defaultPermissions.AccessRights -eq 'None') {
Set-MailboxFolderPermission -Identity $calendarPath -User 'Default' -AccessRights AvailabilityOnly
}
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,28 @@
# A simple script to enable forwarding for a list of users from a CSV file
#
# The script is expecting the CSV file to have two columns called SourceAddress and DestinationAddress
#
# Get the list of users from a CSV file
$userList = Import-Csv -Path 'C:\Temp\UserList.csv'
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Get all non-inherited permissions excluding self and output to a CSV file named for each group
foreach ($user in $userList) {
Write-Output -InputObject ('Forwarding ' + $user.SourceAddress + ' to ' + $user.DestinationAddress)
Set-Mailbox -Identity $user.SourceAddress -ForwardingSmtpAddress $user.DestinationAddress
}
# Pull back a list to check everything has worked correctly
foreach ($user in $userList) {
Get-Mailbox -Identity $user.SourceAddress | Select-Object UserPrincipalName,ForwardingSmtpAddress,DeliverToMailboxAndForward
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,52 @@
# Create and set up a room mailbox.
#
# Uses the new PowerShell "module" that support MFA.
#
# New room name and alias
$displayName = ''
$mailboxAlias = ''
# How many people can the room take?
$roomCapacity = ''
# Do you want meeting requests to be auto accepted?
$requestAutoAccept = $true
# Do we want to add the room to a room list?
$addToRoomList = $true
# What is the room list called? (Will be created if it doesn't exist)
$roomList = ''
# Find and load the new ExO "module"
$exoModulePath = (Get-ChildItem -Path $env:userprofile -Filter CreateExoPSSession.ps1 -Recurse -Force -ErrorAction SilentlyContinue).DirectoryName[-1]
. "$exoModulePath\CreateExoPSSession.ps1"
# Establish a session to Exchange Online
Connect-EXOPSSession
# Create the new room mailbox
New-Mailbox -Room -Alias $mailboxAlias -Name $displayName -DisplayName $displayName -ResourceCapacity $roomCapacity
# Wait for the meeting room mailbox to process
Start-Sleep -Seconds 30
# Set the mailbox calendar to auto accept meeting requests (assuming policies are met)
if ($requestAutoAccept) {
Set-CalendarProcessing $mailboxAlias -AutomateProcessing AutoAccept
}
# If we're adding the room to a room list, then do that.
if ($addToRoomList) {
# If the room list doesn't exist, create it.
if (!(Get-DistributionGroup -Identity $roomList -ErrorAction SilentlyContinue)) {
New-DistributionGroup -Name $roomList -RoomList
}
# Add the room to the list
Add-DistributionGroupMember -Identity $roomList -Member $mailboxAlias
}
# End the Exchange Session
Get-PSSession | Where-Object {$_.ComputerName -eq 'outlook.office365.com'} | Remove-PSSession

View File

@@ -0,0 +1,76 @@
# ScheduledBitLockerKeyBackup.ps1
<#
Script intended for deployment through Intune:
Creates a locally saved PS script to get the bitlocker key and save it to Azure.
Then creates a scheduled task to run that script at every logon.
#>
# Name and description for the schedulled task to be created
$taskName = 'Bitlocker Key Backup to AzureAD'
$taskDescription = 'Retrieve Bitlocker key for system drive and store it in AzureAD'
# Day, time and randomised delay for the task to be created
$taskDay = 'Monday'
$taskTime = '12:00:00'
$taskDelay = '00:20:00'
# Path to the folder for the files to be created
$scriptFolder = 'C:\ProgramData\Intune\Scripts\'
# Names of the files to be created
$scriptFilename = 'BitlockerKeyBackup.ps1'
$scriptLogFilename = 'BitlockerKeyBackup-LastRun.log'
$deployLogFilename = 'BitlockerKeyBackup-Deployed.log'
# Establish full paths to the files
$scriptPath = $scriptFolder + $scriptFilename
$logPath = $scriptFolder + $scriptLogFilename
$deployLogPath = $scriptFolder + $deployLogFilename
# If folder doesn't exist create it, else clean up files from last run
if (!(Test-Path -Path $scriptFolder)) {
New-Item -Path $scriptFolder -ItemType Directory
}
else {
foreach ($filePath in @($scriptPath, $logPath, $deployLogPath)) {
if (Test-Path -Path $filePath) {
Remove-Item -Path $filePath
}
}
}
# Contents of the PS script file to be created on the target machine
$scriptContents = @(
'$logPath = ''' + $logPath + ''''
'try {'
' $recoveryPassword = ((Get-BitlockerVolume -MountPoint $env:SystemDrive -ErrorAction Stop).KeyProtector | Where-Object {$_.KeyProtectorType -eq "RecoveryPassword"})'
' $result = BackupToAAD-BitLockerKeyProtector $env:systemdrive -KeyProtectorId $recoveryPassword.KeyProtectorId -ErrorAction Stop'
' Out-File -InputObject $result -FilePath $logPath'
'}'
'catch {'
' Out-File -InputObject $Error[0].Exception.Message -FilePath $logPath'
'}'
)
# Create the script file
Out-File -InputObject $scriptContents -FilePath $scriptPath
# Set up the various parts of the scheduled task
$taskArgument = '-ExecutionPolicy Bypass -Command ". ' + $scriptPath + '"'
$taskAction = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument $taskArgument -WorkingDirectory $scriptFolder
$taskTrigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek $taskDay -At $taskTime -RandomDelay $taskDelay
$taskPrincipal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -LogonType 'ServiceAccount' -RunLevel 'Highest'
$taskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Compatibility 'Win8' -Hidden -StartWhenAvailable
# If the scheduled task already exists then remove it
if (Get-ScheduledTask | Where-Object { $_.TaskName -eq $taskName }) {
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
}
# Create the scheduled task and run it immediately
$taskCreated = Register-ScheduledTask -Action $taskAction -Trigger $taskTrigger -TaskName $taskName -Description $taskDescription -Principal $taskPrincipal -Settings $taskSettings
Start-ScheduledTask -TaskName $taskName
# Create a log file for the deployment of the scheduled task
Out-File -InputObject $taskCreated -FilePath $deployLogPath

View File

@@ -0,0 +1,4 @@
# Convert AD GUID to 365 ImmutableID
$adGuid = Read-Host -Prompt 'Enter Active Directory GUID to convert to ImmutableID'
[System.Convert]::ToBase64String($adGuid.tobytearray())

View File

@@ -0,0 +1,22 @@
# Bulk add a new licence to users on the basis of what licence they currently have
#
# This is useful for something like adding Office 365 ATP to everyone who currently has E3, for example.
#
# What licence do the users currently have?
$existingLicence = ''
# What licence are we adding?
$licenceToAdd = ''
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Find everyone who has the existing
$users = Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match $existingLicence -and !(($_.licenses).AccountSkuId -match $licenceToAdd)}
# Add the new licence
foreach ($user in $users) {
Set-MSOLUserLicense -UserPrincipalName $user.UserPrincipalName AddLicenses $licenceToAdd
}

View File

@@ -0,0 +1,37 @@
# Bulk add additional licences to a list of users where they already have a licence assigned.
#
# Only works where the user already has a licence assigned as assigning a licence to an unlicenced user is a different process.
#
# Where is the list of user UPN's?
$userListPath = 'C:\Temp\UserList.txt'
# What licences are we adding?
# List of available SKUs can be obtained with (Get-MsolAccountSku).AccountSkuId
$licencesToAdd = @('','')
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Import list of users from file
$users = Get-Content -Path $userListPath | Sort-Object
# Add the new licence
foreach ($user in $users) {
$userDetails = Get-MSOLUser -UserPrincipalName $user
foreach ($licenceToAdd in $licencesToAdd) {
if ($userDetails.IsLicensed -eq $true) {
if (!(($userDetails.licenses).AccountSkuId -match $licenceToAdd)) {
Write-Output -InputObject ('Adding Licence ' + $licenceToAdd + ' to ' + $user + '.')
Set-MSOLUserLicense -UserPrincipalName $user AddLicenses $licenceToAdd
}
else {
Write-Output -InputObject ('User ' + $user + ' already has ' + $licenceToAdd + ' licence assigned.')
}
}
else {
Write-Output -InputObject ('User ' + $user + ' has no existing licence assigned.')
}
}
}

View File

@@ -0,0 +1,42 @@
# Bulk enable or disable MFA for all users in a tenant
#
# Enable or disable MFA?
$enableMFA = $true
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Enable or disable MFA
if ($enableMFA) {
# Create an object containing the authentication requirements
$authReq = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
# Include all relying parties
$authReq.RelyingParty = '*'
# Set MFA state to enabled
# Enabled allows connected apps to keep working until the user completes MFA set up.
# This can also be set to enforced which would disconnect everything immediately.
$authReq.State = 'Enabled'
# Set the cut off date before which registered devices should require re-connecting with MFA.
# Using the current date is recommended so that all previously connected devices have to be reconnected.
$authReq.RememberDevicesNotIssuedBefore = (Get-Date)
# Find all licenced users who do not currently have MFA enabled or enforced
$usersToChange = Get-MsolUser | Where-Object {$_.StrongAuthenticationRequirements.State -notmatch 'Enabled|Enforced' -and $_.isLicensed -eq $true}
# Enable MFA for those users
$usersToChange | Set-MsolUser -StrongAuthenticationRequirements $authReq
}
else {
# Find all licenced users who currently have MFA enabled or enforced
$usersToChange = Get-MsolUser | Where-Object {$_.StrongAuthenticationRequirements.State -match 'Enabled|Enforced' -and $_.isLicensed -eq $true}
# Disable MFA for those users
$usersToChange | Set-MsolUser -StrongAuthenticationRequirements @()
}

View File

@@ -0,0 +1,22 @@
# Bulk update Online User UPNs
#
# What domain are we replacing?
$oldDomain = ''
# What are we replacing it with?
$newDomain = ''
# Import the MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Get all users using that domain as their UPN
$users = Get-MsolUser -All | Where-Object {$_.UserPrincipalName -match $oldDomain}
# Run through the users replacing their UPN and keeping us updated on what's going on
foreach ($user in $users) {
$newUPN = $user.UserPrincipalName.Split('@')[0] + '@' + $newDomain
Write-Output -InputObject ('Setting UPN for user ' + $user.UserPrincipalName + ' to ' + $newUPN)
Set-MsolUserPrincipalName -UserPrincipalName $user.UserPrincipalName -NewUserPrincipalName $newUPN
}

View File

@@ -0,0 +1,12 @@
# Disable MFA for all licenced users who currently have it enabled
#
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Find all licenced users who currently have MFA enabled or enforced
$usersToChange = Get-MsolUser | Where-Object {$_.StrongAuthenticationRequirements.State -match 'Enabled|Enforced' -and $_.isLicensed -eq $true}
# Disable MFA for those users
$usersToChange | Set-MsolUser -StrongAuthenticationRequirements @()

View File

@@ -0,0 +1,26 @@
# Enable MFA for all licenced users who don't currently have it enabled
#
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Create an object containing the authentication requirements
$authReq = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
# Include all relying parties
$authReq.RelyingParty = '*'
# Set MFA state to enabled
# Enabled allows connected apps to keep working until the user completes MFA set up.
# This can also be set to enforced which would disconnect everything immediately.
$authReq.State = 'Enabled'
# Set the cut off date before which registered devices should require re-connecting with MFA
$authReq.RememberDevicesNotIssuedBefore = (Get-Date)
# Find all licenced users who do not currently have MFA enabled or enforced
$usersToChange = Get-MsolUser | Where-Object {$_.StrongAuthenticationRequirements.State -notmatch 'Enabled|Enforced' -and $_.isLicensed -eq $true}
# Enable MFA for those users
$usersToChange | Set-MsolUser -StrongAuthenticationRequirements $authReq

View File

@@ -0,0 +1,17 @@
# Bulk remove a licence from users
#
# What licence are we removing?
$licenceToRemove = ''
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Find everyone who has the licence to be removed
$users = Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match $licenceToRemove}
# Remove the licence
foreach ($user in $users) {
Set-MSOLUserLicense user $user.UserPrincipalName RemoveLicenses $licenceToRemove
}

View File

@@ -0,0 +1,21 @@
# Bulk replace a licence for all users who have the one being replaced.
#
# What licence are we removing?
$licenceToRemove = ''
# What licence are we adding?
$licenceToAdd = ''
# Import MSOnline module and connect
Import-Module MSOnline
Connect-MsolService
# Find everyone who has the licence being replaced
$users = Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match $licenceToRemove}
# Remove the old licence and add the new one
foreach ($user in $users) {
Set-MSOLUserLicense user $user.UserPrincipalName RemoveLicenses $licenceToRemove
Set-MSOLUserLicense user $user.UserPrincipalName -AddLicenses $licenceToAdd
}

View File

@@ -0,0 +1,16 @@
# Update Online User UPN - when AD sync doesn't do it.
# Import the MSOL module and connect
Import-Module MSOnline
Connect-MsolService
# Whose UPN are we changing?
$oldUPN = Read-Host -Prompt 'Enter user''s old UPN in the format username@domain'
# What are we changing it to?
$newUPN = Read-Host -Prompt 'Enter user''s new UPN in the format username@domain'
# Change the UPN
if (Get-ADUser -Identity $newUPN.Split('@')[0]) {
Set-MsolUserPrincipalName -UserPrincipalName $oldUPN -NewUserPrincipalName $newUPN
}

View File

@@ -0,0 +1,9 @@
# Delete a user and then delete the deleted user
Import-Module MSOnline
Connect-MsolService
$upnToDelete = Read-Host -Prompt 'Enter UPN of user to delete in the format username@domain'
Remove-MsolUser -UserPrincipalName $upnToDelete
Remove-MsolUser -UserPrincipalName $upnToDelete -RemoveFromRecycleBin

View File

@@ -0,0 +1,33 @@
# Remove a duplicate 365 account created by a faulty sync and reconnect
# the orphaned 365 user to the AD account.
#
# Get correct and incorrect account details
$adUsername = Read-Host -Prompt 'Enter username for AD account'
$msolIncorrectUPN = Read-Host -Prompt 'Enter UPN for the duplicate object in MSOL'
# Connect to MS Online
Import-Module MSOnline
Connect-MsolService
# Get AD user account
$adObject = Get-ADUser -Identity $adUsername
# Get correct UPN from AD account
$msolCorrectUPN = $adObject.UserPrincipalName
#
try {
Get-MsolUser -UserPrincipalName $msolCorrectUPN -ErrorAction Stop
Remove-MSOLuser -UserPrincipalName $msolIncorrectUPN
Remove-MSOLuser -UserPrincipalName $msolIncorrectUPN -RemoveFromRecycleBin
$adGuid = $adObject.ObjectGuid
$immutableID = [System.Convert]::ToBase64String($adGuid.ToByteArray())
Set-MSOLuser -UserPrincipalName $msolCorrectUPN -ImmutableID $immutableID
}
catch {
Write-Host 'No account found in Azure AD matching the UPN for that AD account.'
}

View File

@@ -0,0 +1,4 @@
# Convert 365 ImmutableID to AD GUID
$immutableID = Read-Host -Prompt 'Enter ImmutableID to convert to Active Directory GUID'
[GUID][System.Convert]::FromBase64String($immutableID)

View File

@@ -0,0 +1,18 @@
# Retrive a list of all OneDrive for Business sites within the organisation
#
# Requires the Sharepoint Online PowerShell module to be installed
#
# The name of your Office 365 organization
# This can be found in your Sharepoint URL before the '-my', eg: https://thecompany-my.sharepoint.com/
$spoTenantName=''
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Create the common base URL for OneDrive for Business
$spoBaseWildcard = 'https://' + $spoTenantName + '-my.sharepoint.com/personal/*'
# Get a list of all 'personal' sites (e.g.: OneDrive for Business sites) within the tenant
Get-SPOSite -Limit all -IncludePersonalSite $true | Where-Object {$_.Url -like $spoBaseWildcard} | Select-Object Owner,URL,StorageQuota | Format-Table -AutoSize

View File

@@ -0,0 +1,47 @@
# Increase the size of specific users' OneDrive for Business accounts
#
# Requires the Sharepoint Online PowerShell module to be installed
#
# The name of your Office 365 organization
# This can be found in your Sharepoint URL before the '-my', eg: https://thecompany-my.sharepoint.com/
$spoTenantName=''
# The size you want to increase to in TB.
$newSize = 1
# The list of UPNs for the accounts you wich to add the secondary admin to (list can contain a single item if required)
$userList = @('','')
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Create the base URL for OneDrive for Business
$spoBaseURL = 'https://' + $spoTenantName + '-my.sharepoint.com/personal/'
# Convert new size to bytes
$newBytes = $newSize * 1048576
# Increase size for each user in list
foreach ($userUPN in $userList) {
$spoURL = $spoBaseURL + ($userUPN.ToLower() -replace "[@.]", "_")
try {
$currentBytes = (Get-SPOSite -Identity $spoURL -ErrorAction:Stop).StorageQuota
if ($currentBytes -gt $newBytes) {
try {
Set-SPOSite -Identity $spoURL -StorageQuota $newBytes -ErrorAction:Stop
Write-Output -InputObject ('Updated OneDrive account limit for ' + $userUPN + ' to ' + $newSize + 'TB.')
}
catch {
Write-Output -InputObject ('Failed to update OneDrive account limit for ' + $userUPN + '.')
}
}
else {
Write-Output -InputObject ('OneDrive account limit for ' + $userUPN + ' already equal to or higher than ' + $newSize + 'TB.')
}
}
catch {
Write-Output -InputObject ('No OneDrive account found for ' + $userUPN + '.')
}
}

View File

@@ -0,0 +1,44 @@
# Increase the size of all users' OneDrive for Business accounts
#
# Requires the Sharepoint Online PowerShell module to be installed
#
# The name of your Office 365 organization
# This can be found in your Sharepoint URL before the '-my', eg: https://thecompany-my.sharepoint.com/
$spoTenantName=''
# The size you want to increase to in TB.
$newSize = 1
# Connect to Sharepoint Online
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService -Url ('https://' + $spoTenantName + '-admin.sharepoint.com')
# Create the common base URL for OneDrive for Business
$spoBaseWildcard = 'https://' + $spoTenantName + '-my.sharepoint.com/personal/*'
# Convert new size to bytes
$newBytes = $newSize * 1048576
# Get a list of all personal sites within the tenant.
$personalSites = Get-SPOSite -Limit all -IncludePersonalSite $true | Where-Object {$_.Url -like $spoBaseWildcard}
# Increase size for each user in turn.
foreach ($personalSite in $personalSites) {
$spoURL = $personalSite.Url
$userUPN = $personalSite.Owner
$currentBytes = $personalSite.StorageQuota
if ($currentBytes -lt $newBytes) {
try {
Set-SPOSite -Identity $spoURL -StorageQuota $newBytes -ErrorAction:Stop
Write-Output -InputObject ('Updated OneDrive account limit for ' + $userUPN + ' to ' + $newSize + 'TB.')
}
catch {
Write-Output -InputObject ('Failed to update OneDrive account limit for ' + $userUPN + '.')
}
}
else {
Write-Output -InputObject ('OneDrive account limit for ' + $userUPN + ' already equal to or higher than ' + $newSize + 'TB.')
}
}

Some files were not shown because too many files have changed in this diff Show More