�����JFIF��XX����������    $.' ",#(7),01444'9=82<.342  2!!22222222222222222222222222222222222222222222222222�����"����4���������������������������� ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������,�PG"Z_�4�˷����kjز�Z�,F+��_z�,�© �����zh6�٨�ic�fu������������������������������������#ډb���_�N��?�����������wQ���5-�~�I���8���������������������������������TK<5o�Iv-������������������k�_U_������������������������������~b�M��d��������Ӝ�U�Hh��?]��E�w��Q���k�{��_}qFW7HTՑ��Y��F�����?_�'ϔ��_�Ջt������������������������=||I �����6�έ"�����D���/[�k�9����Y�8������ds|\���Ҿp6�Ҵ���]��.����6���z<�v��@]�i%������������������������$j��~����g��J>��no����pM[me�i$[�����������s�o�ᘨ�˸ nɜG-�ĨU�ycP���3.DB�li�;���������������������hj���x����7Z^�N�h��������N3u{�:j�����x�힞��#M��&��jL P@��_���� P�������������������&��o8��������9������@Sz���6�t7#O�ߋ �����s}Yf�T������lmr����Z)'N��k�۞p�����w\�T���������������ȯ?�8`���O��i{wﭹW�[�r�� ��Q4F�׊������3m&L�=��h3�������z~��#����\�l :�F,j@�� ʱ�wQT����8�"kJO����6�֚l������������������}����R�>ډK���]��y����&����p�}b������;N�1�m�r$����|��7�>e�@���B�TM*-i�H��g�D�)� E�m�|�ؘbҗ�a���Ҿ����������������t4�����o���G��*oCN�rP���Q��@z,|?W[0���������:�n,j���WiE��W������$~/�hp\��?��{(�0���+�Y8rΟ�+����>S-S���������������VN;���}�s?.����� w��9��˟<���Mq4�Wv'������{)0�1mB����V����W[��������8�/<� �%���wT^�5���b��)iM� p�g�N�&ݝ������������VO~��q���u���9��� ����!��J27�����$����O-���! �:���%H��� ـ�������y�ΠM=t{!S�� �oK8�������t<����è��������:a��������[������ա�H���~��w��Qz`�p����o�^ ������Q��n����� �,uu�C��$ ^���,�������8�#��:�6��e�|~�����������!�3��3.�\0�����q��o�4`.|� ����y�Q�`~;�d�ׯ,��O�Zw�������`73�v�܋�<�����Ȏ�� ـ4k��5�K�a�u�=9Yd��$>x�A�&�� j0� ���vF��� Y���|�y��� ~�6�@c��1vOp��������Ig�����4��l�OD�����L����� R���c���j�_�uX�6��3?nk��Wy�f;^*B� ��@���~a�`��Eu�������+�����6�L��.ü>��}y���}_�O�6�͐�:�Yr���G�X��kG������l^w����������~㒶sy���Iu�!���� W ��X��N�7BV��O��!X�2����wvG�R�f�T#�����t�/?���%8�^�W�aT����G�cL�M���I��(J����1~�8�?aT ���]����AS�E��(��*E}� 2������#I/�׍qz��^t�̔���������b�Yz4x����t�){ OH�����+(E��A&�N�������XT��o��"�XC����'���)}�J�z�p� ����~5�}�^����+�6����w��c��Q�|�Lp�d�H��}�(�.|����k��c4^�����"�����Z?ȕ ��a<�������L�!0�39C� �Eu�����C�F�Ew�ç ;�n?�*o���B�8�bʝ���'#Rqf����M}7����]�������s2tcS{�\icTx;�\��7K���P������ʇ Z O-��~�������c>"��?��������P�����E��O�8��@�8��G��Q�g�a�Վ���󁶠��䧘��_%#r�>�����1�z�a���eb��qcP��ѵ��n���#L��� =��׀t� L�7�`�����V����A{�C:�g���e@�����w1 Xp�3�c3�ġ�������p��M"'-�@n4���fG���B3�DJ�8[Jo�ߐ���gK)ƛ��$���� �������8�3�����+���� �����6�ʻ���� ���S�kI�*KZlT _`�������?��K�����QK�d���������B`�s}�>���`������*�>��,*@J�d�oF*�����弝��O}�k��s��]��y�ߘ�������c1G�V���<=�7��7����6��q�PT��tXԀ�!9*4�4Tހ���3XΛex�46�������Y��D ����� ����BdemDa����\�_l,����G�/���֌7���Y�](�xTt^%�GE�����4�}bT����ڹ�����;��Y)���B�Q��u��>J/J ���⮶.�XԄ��j�ݳ������+E��d ���r�5�_D�����1 ���o�� �B�x�΢�#����<��W�����8���R6�@���g�M�.��� dr�D��>(otU��@�x=��~v���2� ӣ�d�oBd�����3�eO�6�㣷����������ݜ�6��6Y��Qz`����S��{���\P��~z m5{J/L��1������<�e�ͅPu���b�]�ϔ��������'�������f�b� Zpw��c`"��i���BD@:)ִ�:�]��h���v�E��w���T�l�������P����"Ju�}��وV ��J��G6��. J/�Qgl߭�e�����@�z�Zev2u����)]կ���������7x�������s�M�-<ɯ�c��r��v�����@��$�ޮ}lk���a����'����>x��O\�Z������Fu>������ck#��&:��`�$��ai�>2Δ����l���oF[h�������lE�ܺ�Π���k:)���`������� $[6�����9�����kOw�\|�����8}������ބ:��񶐕��������I�A1/���=�2[�,�!��.}gN#�u����b���� ~���������݊��}34q�����d�E��L��������c��$���"�[q�U�硬g^��%B ��z���r�p�������J�ru%v\h�����1Y�ne`������ǥ:g����pQM~�^��Xi� ��`S�:V2������9.�P���V������?B�k�� ��������AEvw%�_�9C�Q����wKekP�ؠ�\������;Io d�{ ߞo�c1eP�����\� `����E=���@K<�Y��������eڼ�J����w����{av�F�'�M�@��������������/J��+9p����|]���������Iw &`���8���&�M�hg���[�{�������Xj���%��Ӓ�������������������$��(�����ʹN�������<>�I���RY�����K2�NPlL�ɀ�)��&e��������B+ь����(������������������� � �JTx����_?EZ� }@���� 6�U���뙢ط�z��dWI��n` D����噥�[��uV��"�G&�����Ú����2�g�}&m���������������������?ċ���"����Om#�������������������������� ��{���������������������ON��"S�X���Ne��ysQ���@�������������Fn��Vg�����dX�~nj����������������������]J�<�K]:����FW���b�������62����������=��5f����JKw����bf�X������������������������55��~J �%^�������:�-�QIE��P��v�nZum� z � ~ə ���� ���ة����;�f��\v�������g�8�1��f2�������������������������4;�V���ǔ�)�������������������9���1\������������������������������c��v�/'Ƞ�w������������������$�4�R-��t����������������������������������� e�6�/�ġ �̕Ecy�J���u�B���<�W�ַ~�w[B1L۲�-JS΂�{���΃�������������������������������������������A��20�c#���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@���� 0!1@AP"#2Q`$3V�%45a6�FRUq����� ������^7ׅ,$n��������+��F�`��2X'��0vM��p�L=�������5��8������u�p~���.�`r�����\����O��,ư�0oS ��_�M�����l���4�kv\JSd���x���SW�<��Ae�IX����������$I���w�:S���y���›R��9�Q[���,�5�;�@]�%���u�@ *ro�lbI �� ��+���%m:�͇ZV�����u�̉����θau<�fc�.����{�4Ա� �Q����*�Sm��8\ujqs]{kN���)qO�y�_*dJ�b�7���yQqI&9�ԌK!�M}�R�;�������S�T���1���i[U�ɵz�]��U)V�S6���3$K{��ߊ<�(� E]Զ[ǼENg�����'�\?#)Dkf��J���o��v���'�%ƞ�&K�u��!��b�35LX�Ϸ��63$K�a�;�9>,R��W��3�3� d�JeTYE.Mϧ��-�o�j3+y��y^�c�������VO�9NV\nd�1 ��!͕_)a�v;����թ�M�lWR1��)El��P;��yوÏ�u 3�k�5Pr6<�⒲l�!˞*��u־�n�!�l:����UNW ��%��Chx8vL'��X�@��*��)���̮��ˍ��� ����D-M�+J�U�kvK����+�x8��cY������?�Ԡ��~3mo��|�u@[XeY�C�\Kp�x8�oC�C�&����N�~3-H���� ��MX�s�u<`���~"WL��$8ξ��3���a�)|:@�m�\���^�`�@ҷ)�5p+��6���p�%i)P M���ngc�����#0Aruz���RL+xSS?���ʮ}()#�t��mˇ!��0}}y����<�e� �-ή�Ԩ��X������ MF���ԙ~l L.3���}�V뽺�v������멬��Nl�)�2����^�Iq��a��M��qG��T�����c3#������3U�Ǎ���}��לS�|qa��ڃ�+���-��2�f����/��bz��ڐ�� �ݼ[2�ç����k�X�2�* �Z�d���J�G����M*9W���s{��w���T��x��y,�in�O�v��]���n����P�$��JB@=4�OTI�n��e�22a\����q�d���%�$��(���:���: /*�K[PR�fr\nڙdN���F�n�$�4��[�� U�zƶ����� �mʋ���,�ao�u 3�z� �x��Kn����\[��VFmbE;�_U��&V�Gg�]L�۪&#n%�$ɯ��dG���D�TI=�%+AB�Ru#��b4�1�»x�cs�YzڙJG��f��Il���d�eF'T� iA��T���uC�$����Y��H?����[!G`}���ͪ� �纤Hv\������j�Ex�K���!���OiƸ�Yj�+u-<���'q����uN�*�r\��+�]���<�wOZ.fp�ێ��,-*)V?j-kÊ#�`�r��dV����(�ݽBk�����G�ƛk�QmUڗe��Z���f}|����8�8��a���i��3'J�����~G_�^���d�8w������ R�`(�~�.��u���l�s+g�bv���W���lGc}��u���afE~1�Ue������Z�0�8�=e�� f@/�jqEKQQ�J���oN��J���W5~M>$6�Lt�;$ʳ{���^��6�{����v6���ķܰg�V�cnn �~z�x�«�,2�u�?cE+Ș�H؎�%�Za�)���X>uW�Tz�Nyo����s���FQƤ��$��*�&�LLXL)�1�" L��eO��ɟ�9=���:t��Z���c��Ž���Y?�ӭV�wv�~,Y��r�ۗ�|�y��GaF�����C�����.�+� ���v1���fήJ�����]�S��T��B��n5sW}y�$��~z�'�c ��8 ��� ,! �p��VN�S��N�N�q��y8z˱�A��4��*��'������2n<�s���^ǧ˭P�Jޮɏ�U�G�L�J�*#��<�V��t7�8����TĜ>��i}K%,���)[��z�21z ?�N�i�n1?T�I�R#��m-�����������������1����lA�`��fT5+��ܐ�c�q՝��ʐ��,���3�f2U�եmab��#ŠdQ�y>\��)�SLY����w#��.���ʑ�f��� ,"+�w�~�N�'�c�O�3F�������N<���)j��&��,-� �љ���֊�_�zS���TǦ����w�>��?�������n��U仆�V���e�����0���$�C�d���rP �m�׈e�Xm�Vu� �L��.�bֹ��� �[Դaզ���*��\y�8�Է:�Ez\�0�Kq�C b��̘��cө���Q��=0Y��s�N��S.����3.���O�o:���#���v7�[#߫ ��5�܎�L���Er4���9n��COWlG�^��0k�%<���ZB���aB_���������'=��{i�v�l�$�uC���mƎҝ{�c㱼�y]���W�i ��ߧc��m�H� m�"�"�����;Y�ߝ�Z�Ǔ�����:S#��|}�y�,/k�Ld� TA�(�AI$+I3��;Y*���Z��}|��ӧO��d�v��..#:n��f>�>���ȶI�TX��� 8��y����"d�R�|�)0���=���n4��6ⲑ�+��r<�O�܂~zh�z����7ܓ�HH�Ga롏���nCo�>������a ���~]���R���̲c?�6(�q�;5%� |�uj�~z8R�=X��I�V=�|{v�Gj\gc��q����z�؋%M�ߍ����1y��#��@f^���^�>N������#x#۹��6�Y~�?�dfPO��{��P�4��V��u1E1J �*|���%����JN��`eWu�zk M6���q t[�� ��g�G���v��WIG��u_ft����5�j�"�Y�:T��ɐ���*�;� e5���4����q$C��2d�}���� _S�L#m�Yp��O�.�C�;��c����Hi#֩%+) �Ӎ��ƲV���SYź��g |���tj��3�8���r|���V��1#;.SQ�A[���S������#���`n�+���$��$�I �P\[�@�s��(�ED�z���P��])8�G#��0B��[ى��X�II�q<��9�~[Z멜�Z�⊔IWU&A>�P~�#��dp<�?����7���c��'~���5 ��+$���lx@�M�dm��n<=e�dyX��?{�|Aef ,|n3�<~z�ƃ�uۧ�����P��Y,�ӥQ�*g�#먙R�\���;T��i,��[9Qi歉����c>]9�� ��"�c��P�� �Md?٥��If�ت�u��k��/����F��9�c*9��Ǎ:�ØF���z�n*�@|I�ށ9����N3{'��[�'ͬ�Ҳ4��#}��!�V� Fu��,�,mTIk���v C�7v���B�6k�T9��1�*l� '~��ƞF��lU��'�M ����][ΩũJ_�{�i�I�n��$����L�� j��O�dx�����kza۪��#�E��Cl����x˘�o�����V���ɞ�ljr��)�/,�߬h�L��#��^��L�ф�,íMƁe�̩�NB�L�����iL����q�}��(��q��6IçJ$�W�E$��:������=#����(�K�B����zђ <��K(�N�۫K�w��^O{!����)��H���>x�������lx�?>Պ�+�>�W���,Ly!_�D���Ō�l���Q�!�[ �S����J��1��Ɛ�Y}��b,+�Lo�x�ɓ)����=�y�oh�@�꥟/��I��ѭ=��P�y9��� �ۍYӘ�e+�p�Jnϱ?V\SO%�(�t� ���=?MR�[Ș�����d�/ ��n�l��B�7j� ��!�;ӥ�/�[-���A�>��dN�sLj ��,ɪv��=1c�.SQ�O3�U���ƀ�ܽ�E����������̻��9G�ϷD�7(�}��Ävӌ\��y�_0[w ���<΍>����a_��[0+�L��F.�޺��f�>oN�T����q;���y\��bՃ��y�jH�<|q-eɏ�_?_9+P���Hp$�����[ux�K w�Mw��N�ی'$Y2�=��q���KB��P��~�������Yul:�[<����F1�2�O���5=d����]Y�sw:���Ϯ���E��j,_Q��X��z`H1,#II ��d�wr��P˂@�ZJV����y$�\y�{}��^~���[:N����ߌ�U�������O��d�����ؾe��${p>G��3c���Ė�lʌ�� ת��[��`ϱ�-W����dg�I��ig2��� ��}s ��ؤ(%#sS@���~���3�X�nRG�~\jc3�v��ӍL��M[JB�T��s3}��j�Nʖ��W����;7���ç?=X�F=-�=����q�ߚ���#���='�c��7���ڑW�I(O+=:uxq�������������e2�zi+�kuG�R��������0�&e�n���iT^J����~\jy���p'dtG��s����O��3����9* �b#Ɋ�� p������[Bws�T�>d4�ۧs���nv�n���U���_�~,�v����ƜJ1��s�� �QIz���)�(lv8M���U=�;����56��G���s#�K���MP�=��LvyGd��}�VwWBF�'�à �?MH�U�g2�� ����!�p�7Q��j��ڴ����=��j�u��� Jn�A s���uM������e��Ɔ�Ҕ�!)�'��8Ϣ�ٔ���ޝ(��Vp���צ֖d=�IC�J�Ǡ{q������kԭ�߸���i��@K����u�|�p=..�*+����x�����z[Aqġ#s2a�Ɗ���RR�)*HRsi�~�a &f��M��P����-K�L@��Z��Xy�'x�{}��Zm+���:�)�) IJ�-i�u���� ���ܒH��'��L(7�y�GӜq���� j��� 6ߌg1�g�o���,kر���tY�?W,���p���e���f�OQS��!K�۟cҒA�|ս�j�>��=⬒��˧L[�� �߿2JaB~R��u�:��Q�] �0H~���]�7��Ƽ�I���(�}��cq '�ήET���q�?f�ab���ӥvr� �)o��-Q��_'����ᴎo��K������;��V���o��%���~OK ����*��b�f:���-ťIR��`B�5!RB@���ï�� �u �̯e\�_U�_������� g�ES��3��������QT��a�����x����U<~�c?�*�#]�MW,[8O�a�x��]�1bC|踤�P��lw5V%�)�{t�<��d��5���0i�XSU��m:��Z�┵�i�"��1�^B�-��P�hJ��&)O��*�D��c�W��vM��)����}���P��ܗ-q����\mmζZ-l@�}��a��E�6��F�@��&Sg@���ݚ�M����� ȹ 4����#p�\H����dYDo�H���"��\��..R�B�H�z_�/5˘����6��KhJR��P�mƶi�m���3��,#c�co��q�a)*P�t����R�m�k�7x�D�E�\Y�閣_X�<���~�)���c[[�BP����6�Yq���S��0����%_����;��Àv�~�| VS؇ ��'O0��F0��\���U�-�d@�����7�SJ*z��3n��y��P����O����������m�~�P�3|Y��ʉr#�C�<�G~�.,! ���bqx���h~0=��!ǫ�jy����l��O,�[B��~��|9��ٱ����Xly�#�i�B��g%�S��������tˋ���e���ې��\[d�t)��.+u�|1 ������#�~Oj����hS�%��i.�~X���I�H�m��0n���c�1uE�q��cF�RF�o���7� �O�ꮧ� ���ۛ{��ʛi5�rw?׌#Qn�TW��~?y$��m\�\o����%W� ?=>S�N@�� �Ʈ���R����N�)�r"C�:��:����� �����#��qb��Y�. �6[��2K����2u�Ǧ�HYR��Q�MV��� �G�$��Q+.>�����nNH��q�^��� ����q��mM��V��D�+�-�#*�U�̒ ���p욳��u:�������IB���m����PV@O���r[b= �� ��1U�E��_Nm�yKbN�O���U�}�the�`�|6֮P>�\2�P�V���I�D�i�P�O;�9�r�mAHG�W�S]��J*�_�G��+kP�2����Ka�Z���H�'K�x�W�MZ%�O�YD�Rc+o��?�q��Ghm��d�S�oh�\�D�|:W������UA�Qc yT�q��������~^�H��/��#p�CZ���T�I�1�ӏT����4��"�ČZ�����}��`w�#�*,ʹ�� ��0�i��課�Om�*�da��^gJ݅{���l�e9uF#T�ֲ��̲�ٞC"�q���ߍ ոޑ�o#�XZTp����@ o�8��(jd��xw�]�,f���`~��|,s��^����f�1���t��|��m�򸄭/ctr��5s��7�9Q�4�H1꠲BB@�l9@���C�����+�wp�xu�£Yc�9��?`@#�o�mH�s2��)�=��2�.�l����jg�9$�Y�S�%*L������R�Y������7Z���,*=�䷘$�������arm�o�ϰ���UW.|�r�uf����IGw�t����Zwo��~5 ��YյhO+=8fF�)�W�7�L9lM�̘·Y���֘YLf�큹�pRF���99.A �"wz��=E\Z���'a� 2��Ǚ�#;�'}�G���*��l��^"q��+2FQ� hj��kŦ��${���ޮ-�T�٭cf�|�3#~�RJ����t��$b�(R��(����r���dx� >U b�&9,>���%E\� Ά�e�$��'�q't��*�א���ެ�b��-|d���SB�O�O��$�R+�H�)�܎�K��1m`;�J�2�Y~9��O�g8=vqD`K[�F)k�[���1m޼c��n���]s�k�z$@��)!I �x՝"v��9=�ZA=`Ɠi �:�E��)`�7��vI��}d�YI�_ �o�:ob���o ���3Q��&D&�2=�� �Ά��;>�h����y.*ⅥS������Ӭ�+q&����j|UƧ�����}���J0��WW< ۋS�)jQR�j���Ư��rN)�Gű�4Ѷ(�S)Ǣ�8��i��W52���No˓� ۍ%�5brOn�L�;�n��\G����=�^U�dI���8$�&���h��'���+�(������cȁ߫k�l��S^���cƗjԌE�ꭔ��gF���Ȓ��@���}O���*;e�v�WV���YJ\�]X'5��ղ�k�F��b 6R�o՜m��i N�i�����>J����?��lPm�U��}>_Z&�KK��q�r��I�D�Չ~�q�3fL�:S�e>���E���-G���{L�6p�e,8��������QI��h��a�Xa��U�A'���ʂ���s�+טIjP�-��y�8ۈZ?J$��W�P� ��R�s�]��|�l(�ԓ��sƊi��o(��S0���Y� 8�T97.�����WiL��c�~�dxc�E|�2!�X�K�Ƙਫ਼�$((�6�~|d9u+�qd�^3�89��Y�6L�.I�����?���iI�q���9�)O/뚅����O���X��X�V��ZF[�یgQ�L��K1���RҖr@v�#��X�l��F���Нy�S�8�7�kF!A��sM���^rkp�jP�DyS$N���q���nxҍ!U�f�!eh�i�2�m����`�Y�I�9r�6� �TF���C}/�y�^���Η���5d�'��9A-��J��>{�_l+�`��A���[�'��յ�ϛ#w:݅�%��X�}�&�PSt�Q�"�-��\縵�/����$Ɨh�Xb�*�y��BS����;W�ջ_mc�����vt?2}1�;qS�d�d~u:2k5�2�R�~�z+|HE!)�Ǟl��7`��0�<�,�2*���Hl-��x�^����'_TV�gZA�'j� ^�2Ϊ��N7t�����?w�� �x1��f��Iz�C-Ȗ��K�^q�;���-W�DvT�7��8�Z�������� hK�(P:��Q- �8�n�Z���܃e貾�<�1�YT<�,�����"�6{�/ �?�͟��|1�:�#g��W�>$����d��J��d�B���=��jf[��%rE^��il:��B���x���Sּ�1հ��,�=��*�7 fcG��#q� �eh?��2�7�����,�!7x��6�n�LC�4x��},Geǝ�tC.��vS �F�43��zz\��;QYC,6����~;RYS/6���|2���5���v��T��i����������mlv��������&� �nRh^ejR�LG�f���? �ۉҬܦƩ��|��Ȱ����>3����!v��i�ʯ�>�v��オ�X3e���_1z�Kȗ\<������!�8���V��]��?b�k41�Re��T�q��mz��TiOʦ�Z��Xq���L������q"+���2ۨ��8}�&N7XU7Ap�d�X��~�׿��&4e�o�F��� �H�����O���č�c�� 懴�6���͉��+)��v;j��ݷ�� �UV�� i��� j���Y9GdÒJ1��詞�����V?h��l�����l�cGs�ځ�������y�Ac������\V3�? �� ܙg�>qH�S,�E�W�[�㺨�uch�⍸�O�}���a��>�q�6�n6�����N6�q��������N� ���! 1AQaq�0@����"2BRb�#Pr���3C`��Scst���$4D���%Td���� ?�����N����a��3��m���C���w��������xA�m�q�m����m������$����4n淿t'��C"w��zU=D�\R+w�p+Y�T�&�պ@��ƃ��3ޯ?�Aﶂ��aŘ���@-�����Q�=���9D��ռ�ѻ@��M�V��P��܅�G5�f�Y<�u=,EC)�<�Fy'�"�&�չ�X~f��l�KԆV��?�� �W�N����=(� �;���{�r����ٌ�Y���h{�١������jW����P���Tc�����X�K�r��}���w�R��%��?���E��m�� �Y�q|����\lEE4����r���}�lsI�Y������f�$�=�d�yO����p�����yBj8jU�o�/�S��?�U��*������ˍ�0�������u�q�m [�?f����a�� )Q�>����6#������� ?����0UQ����,IX���(6ڵ[�DI�MNލ�c&���υ�j\��X�R|,4��� j������T�hA�e��^���d���b<����n�� �즇�=!���3�^�`j�h�ȓr��jẕ�c�,ٞX����-����a�ﶔ���#�$��]w�O��Ӫ�1y%��L�Y<�wg#�ǝ�̗`�x�xa�t�w��»1���o7o5��>�m뭛C���Uƃߜ}�C���y1Xνm�F8�jI���]����H���ۺиE@I�i;r�8ӭ�����V�F�Շ| ��&?�3|x�B�MuS�Ge�=Ӕ�#BE5G������Y!z��_e��q�р/W>|-�Ci߇�t�1ޯќd�R3�u��g�=0 5��[?�#͏��q�cf���H��{ ?u�=?�?ǯ���}Z��z���hmΔ�BFTW�����<�q��(v� ��!��z���iW]*�J�V�z��gX֧A�q�&��/w���u�gYӘa���; �i=����g:��?2�dž6�ى�k�4�>�Pxs����}������G�9���3 ���)gG�R<>r h�$��'nc�h�P��Bj��J�ҧH� -��N1���N��?��~��}-q!=��_2hc�M��l�vY%UE�@|�v����M2�.Y[|y�"Eï��K�ZF,�ɯ?,q�?v�M 80jx�"�;�9vk�����+ ֧�� �ȺU��?�%�vcV��mA�6��Qg^M�����A}�3�nl� QRN�l8�kkn�'�����(��M�7m9و�q���%ޟ���*h$Zk"��$�9��: �?U8�Sl��,,|ɒ��xH(ѷ����Gn�/Q�4�P��G�%��Ա8�N��!� �&�7�;���eKM7�4��9R/%����l�c>�x;������>��C�:�����t��h?aKX�bhe�ᜋ^�$�Iհ �hr7%F$�E��Fd���t��5���+�(M6�t����Ü�UU|zW�=a�Ts�Tg������dqP�Q����b'�m���1{|Y����X�N��b �P~��F^F:����k6�"�j!�� �I�r�`��1&�-$�Bevk:y���#y�w��I0��x��=D�4��tU���P�ZH��ڠ底taP��6����b>�xa�����Q�#� WeF��ŮNj�p�J* mQ�N�����*I�-*�ȩ�F�g�3 �5��V�ʊ�ɮ�a��5F���O@{���NX��?����H�]3��1�Ri_u��������ѕ�� ����0��� F��~��:60�p�͈�S��qX#a�5>���`�o&+�<2�D����: �������ڝ�$�nP���*)�N�|y�Ej�F�5ټ�e���ihy�Z �>���k�bH�a�v��h�-#���!�Po=@k̆IEN��@��}Ll?j�O������߭�ʞ���Q|A07x���wt!xf���I2?Z��<ץ�T���cU�j��]���陎Ltl �}5�ϓ��$�,��O�mˊ�;�@O��jE��j(�ا,��LX���LO���Ц�90�O �.����a��nA���7������j4 ��W��_ٓ���zW�jcB������y՗+EM�)d���N�g6�y1_x��p�$Lv�:��9�"z��p���ʙ$��^��JԼ*�ϭ����o���=x�Lj�6�J��u82�A�H�3$�ٕ@�=Vv�]�'�qEz�;I˼��)��=��ɯ���x �/�W(V���p�����$ �m�������u�����񶤑Oqˎ�T����r��㠚x�sr�GC��byp�G��1ߠ�w e�8�$⿄����/�M{*}��W�]˷.�CK\�ުx���/$�WP�w���r� |i���&�}�{�X� �>��$-��l���?-z���g����lΆ���(F���h�vS*���b���߲ڡn,|)mrH[���a�3�ר�[1��3o_�U�3�TC�$��(�=�)0�kgP���� ��u�^=��4 �WYCҸ:��vQ�ר�X�à��tk�m,�t*��^�,�}D*�� �"(�I��9R����>`�`��[~Q]�#af��i6l��8���6�:,s�s�N6�j"�A4���IuQ��6E,�GnH��zS�HO�uk�5$�I�4��ؤ�Q9�@��C����wp��BGv[]�u�Ov����0I4���\��y�����Q�Ѹ��~>Z��8�T��a��q�ޣ;z��a���/��S��I:�ܫ_�|������>=Z����8:�S��U�I�J��"IY���8%b8���H��:�QO�6�;7�I�S��J��ҌAά3��>c���E+&jf$eC+�z�;��V����� �r���ʺ������my�e���aQ�f&��6�ND���.:��NT�vm�<- u���ǝ\MvZY�N�NT��-A�>jr!S��n�O 1�3�Ns�%�3D@���`������ܟ 1�^c<���� �a�ɽ�̲�Xë#�w�|y�cW�=�9I*H8�p�^(4���՗�k��arOcW�tO�\�ƍR��8����'�K���I�Q�����?5�>[�}��yU�ײ -h��=��% q�ThG�2�)���"ו3]�!kB��*p�FDl�A���,�eEi�H�f�Ps�����5�H:�Փ~�H�0Dت�D�I����h�F3�������c��2���E��9�H��5�zԑ�ʚ�i�X�=:m�xg�hd(�v����׊�9iS��O��d@0ڽ���:�p�5�h-��t�&���X�q�ӕ,��ie�|���7A�2���O%P��E��htj��Y1��w�Ѓ!����  ���� ࢽ��My�7�\�a�@�ţ�J ��4�Ȼ�F�@o�̒?4�wx��)��]�P��~�����u�����5�����7X ��9��^ܩ�U;Iꭆ 5 �������eK2�7(�{|��Y׎ �V��\"���Z�1� Z�����}��(�Ǝ"�1S���_�vE30>���p;� ΝD��%x�W�?W?v����o�^V�i�d��r[��/&>�~`�9Wh��y�;���R���� ;;ɮT��?����r$�g1�K����A��C��c��K��l:�'��3 c�ﳯ*"t8�~l��)���m��+U,z��`(��>yJ�?����h>��]��v��ЍG*�{`��;y]��I�T� ;c��NU�fo¾h���/$���|NS���1�S�"�H��V���T���4��uhǜ�]�v;���5�͠x��'C\�SBpl���h}�N����� A�Bx���%��ޭ�l��/����T��w�ʽ]D�=����K���ž�r㻠l4�S�O?=�k �M:� ��c�C�a�#ha���)�ѐxc�s���gP�iG���{+���x���Q���I= �� z��ԫ+ �8"�k�ñ�j=|����c ��y��CF��/���*9ж�h{ �?4�o� ��k�m�Q�N�x��;�Y��4膚�a�w?�6�>�e]�����Q�r�:����g�,i"�����ԩA��*M�<�G��b�if��l^M��5�� �Ҩ�{����6J��ZJ�����P�*�����Y���ݛu�_4�9�I8�7���������,^ToR���m4�H��?�N�S�ѕw��/S��甍�@�9H�S�T��t�ƻ���ʒU��*{Xs�@����f������֒Li�K{H�w^���������Ϥm�tq���s� ���ք��f:��o~s��g�r��ט� �S�ѱC�e]�x���a��) ���(b-$(�j>�7q�B?ӕ�F��hV25r[7 Y� }L�R��}����*sg+��x�r�2�U=�*'WS��ZDW]�WǞ�<��叓���{�$�9Ou4��y�90-�1�'*D`�c�^o?(�9��u���ݐ��'PI&� f�Jݮ�������:wS����jfP1F:X �H�9dԯ����˝[�_54 �}*;@�ܨ�� ð�yn�T���?�ןd�#���4rG�ͨ��H�1�|-#���Mr�S3��G�3�����)�.᧏3v�z֑��r����$G"�`j �1t��x0<Ɔ�Wh6�y�6��,œ�Ga��gA����y��b��)���h�D��ß�_�m��ü �gG;��e�v��ݝ�nQ� ��C����-�*��o���y�a��M��I�>�<���]obD��"�:���G�A��-\%LT�8���c�)��+y76���o�Q�#*{�(F�⽕�y����=���rW�\p���۩�c���A���^e6��K������ʐ�cVf5$�'->���ՉN"���F�"�UQ@�f��Gb~��#�&�M=��8�ט�JNu9��D��[̤�s�o�~������� G��9T�tW^g5y$b��Y'��س�Ǵ�=��U-2 #�MC�t(�i� �lj�@Q 5�̣i�*�O����s�x�K�f��}\��M{E�V�{�υ��Ƈ�����);�H����I��fe�Lȣr�2��>��W��I�Ȃ6������i��k�� �5�YOxȺ����>��Y�f5'��|��H+��98pj�n�.O�y�������jY��~��i�w'������l�;�s�2��Y��:'lg�ꥴ)o#'Sa�a�K��Z� �m��}�`169�n���"���x��I ��*+� }F<��cГ���F�P�������ֹ*�PqX�x۩��,� ��N�� �4<-����%����:��7����W���u�`����� $�?�I��&����o��o��`v�>��P��"��l���4��5'�Z�gE���8���?��[�X�7(��.Q�-��*���ތL@̲����v��.5���[��=�t\+�CNܛ��,g�SQnH����}*F�G16���&:�t��4ُ"A��̣��$�b �|����#rs��a�����T�� ]�<�j��B�S�('$�ɻ� �wP;�/�n��?�ݜ��x�F��yUn�~mL*-�������Xf�wd^�a�}��f�,=t�׵i�.2/wpN�Ep8�OР���•��R�FJ� 55TZ��T �ɭ�<��]��/�0�r�@�f��V��V����Nz�G��^���7hZi����k��3�,kN�e|�vg�1{9]_i��X5y7� 8e]�U����'�-2,���e"����]ot�I��Y_��n�(JҼ��1�O ]bXc���Nu�No��pS���Q_���_�?i�~�x h5d'�(qw52] ��'ޤ�q��o1�R!���`ywy�A4u���h<קy���\[~�4�\ X�Wt/� 6�����n�F�a8��f���z �3$�t(���q��q�x��^�XWeN'p<-v�!�{�(>ӽDP7��ո0�y)�e$ٕv�Ih'Q�EA�m*�H��RI��=:��� ���4牢) �%_iN�ݧ�l]� �Nt���G��H�L��� ɱ�g<���1V�,�J~�ٹ�"K��Q�� 9�HS�9�?@��k����r�;we݁�]I�!{ �@�G�[�"��`���J:�n]�{�cA�E����V��ʆ���#��U9�6����j�#Y�m\��q�e4h�B�7��C�������d<�?J����1g:ٳ���=Y���D�p�ц� ׈ǔ��1�]26؜oS�'��9�V�FVu�P�h�9�xc�oq�X��p�o�5��Ա5$�9W�V(�[Ak�aY錎qf;�'�[�|���b�6�Ck��)��#a#a˙��8���=äh�4��2��C��4tm^ �n'c����]GQ$[Wҿ��i���vN�{Fu ��1�gx��1┷���N�m��{j-,��x�� Ūm�ЧS�[�s���Gna���䑴�� x�p 8<������97�Q���ϴ�v�aϚG��Rt�Һ׈�f^\r��WH�JU�7Z���y)�vg=����n��4�_)y��D'y�6�]�c�5̪��\� �PF�k����&�c;��cq�$~T�7j ���nç]�<�g ":�to�t}�159�<�/�8������m�b�K#g'I'.W������6��I/��>v��\�MN��g���m�A�yQL�4u�Lj�j9��#44�t��l^�}L����n��R��!��t��±]��r��h6ٍ>�yҏ�N��fU�� ���� Fm@�8}�/u��jb9������he:A�y�ծw��GpΧh�5����l}�3p468��)U��d��c����;Us/�֔�YX�1�O2��uq�s��`hwg�r~�{ R��mhN��؎*q 42�*th��>�#���E����#��Hv�O����q�}������6�e��\�,Wk�#���X��b>��p}�դ��3���T5��†��6��[��@��P�y*n��|'f�֧>�lư΂�̺����SU�'*�q�p�_S�����M�� '��c�6������m�� ySʨ;M��r���Ƌ�m�Kxo,���Gm�P��A�G�:��i��w�9�}M(�^�V��$ǒ�ѽ�9���|���� �a����J�SQ�a���r�B;����}���ٻ֢�2�%U���c�#�g���N�a�ݕ�'�v�[�OY'��3L�3�;,p�]@�S��{ls��X�'���c�jw��k'a�.��}�}&�� �dP�*�bK=ɍ!����;3n�gΊU�ߴmt�'*{,=SzfD� A��ko~�G�aoq�_mi}#�m�������P�Xhύ�����mxǍ�΂���巿zf��Q���c���|kc�����?���W��Y�$���_Lv����l߶��c���`?����l�j�ݲˏ!V��6����U�Ђ(A���4y)H���p�Z_�x��>���e���R��$�/�`^'3qˏ�-&Q�=?��CFVR �D�fV�9��{�8g�������n�h�(P"��6�[�D���< E�����~0<@�`�G�6����Hг�cc�� �c�K.5��D��d�B���`?�XQ��2��ٿyqo&+�1^� DW�0�ꊩ���G�#��Q�nL3��c���������/��x ��1�1�[y�x�პCW��C�c�UĨ80�m�e�4.{�m��u���I=��f�����0QRls9���f���������9���~f�����Ǩ��a�"@�8���ȁ�Q����#c�ic������G��$���G���r/$W�(��W���V�"��m�7�[m�A�m����bo��D� j����۳� l���^�k�h׽����� ��#� iXn�v��eT�k�a�^Y�4�BN���ĕ���0������� !01@Q"2AaPq3BR�������?�����@4�Q�����T3,���㺠�W�[=JK�Ϟ���2�r^7��vc�:�9 �E�ߴ�w�S#d���Ix��u��:��Hp��9E!�� V 2;73|F��9Y���*ʬ�F��D����u&���y؟��^EA��A��(ɩ���^��GV:ݜDy�`��Jr29ܾ�㝉��[���E;Fzx��YG��U�e�Y�C���� ����v-tx����I�sם�Ę�q��Eb�+P\ :>�i�C'�;�����k|z�رn�y]�#ǿb��Q��������w�����(�r|ӹs��[�D��2v-%��@;�8<a���[\o[ϧw��I!��*0�krs)�[�J9^��ʜ��p1)� "��/_>��o��<1����A�E�y^�C��`�x1'ܣn�p��s`l���fQ��):�l����b>�Me�jH^?�kl3(�z:���1ŠK&?Q�~�{�ٺ�h�y���/�[��V�|6��}�KbX����mn[-��7�5q�94�������dm���c^���h� X��5��<�eޘ>G���-�}�دB�ޟ� ��|�rt�M��V+�]�c?�-#ڛ��^ǂ}���Lkr���O��u�>�-D�ry� D?:ޞ�U��ǜ�7�V��?瓮�"�#���r��չģVR;�n���/_� ؉v�ݶe5d�b9��/O��009�G���5n�W����JpA�*�r9�>�1��.[t���s�F���nQ� V 77R�]�ɫ8����_0<՜�IF�u(v��4��F�k�3��E)��N:��yڮe��P�`�1}�$WS��J�SQ�N�j��ٺ��޵�#l���ј(�5=��5�lǏmoW�v-�1����v,W�mn��߀$x�<����v�j(����c]��@#��1������Ǔ���o'��u+����;G�#�޸��v-lη��/(`i⣍Pm^����ԯ̾9Z��F��������n��1��� ��]�[��)�'�������:�֪�W��FC����� �B9،!?���]��V��A�Վ�M��b�w��G F>_DȬ0¤�#�QR�[V��kz���m�w�"��9ZG�7'[��=�Q����j8R?�zf�\a�=��O�U����*oB�A�|G���2�54 �p��.w7� �� ���&������ξxGHp� B%��$g�����t�Џ򤵍z���HN�u�Я�-�'4��0���;_���3������� !01"@AQa2Pq#3BR�������?����ʩca��en��^��8���<�u#��m*08r��y�N"�<�Ѳ0��@\�p��� �����Kv�D��J8�Fҽ� �f�Y��-m�ybX�NP����}�!*8t(�OqѢ��Q�wW�K��ZD��Δ^e��!� ��B�K��p~�����e*l}z#9ң�k���q#�Ft�o��S�R����-�w�!�S���Ӥß|M�l޶V��!eˈ�8Y���c�ЮM2��tk���� ������J�fS����Ö*i/2�����n]�k�\���|4yX�8��U�P.���Ы[���l��@"�t�<������5�lF���vU�����W��W��;�b�cД^6[#7@vU�xgZv��F�6��Q,K�v��� �+Ъ��n��Ǣ��Ft���8��0��c�@�!�Zq s�v�t�;#](B��-�nῃ~���3g������5�J�%���O������n�kB�ĺ�.r��+���#�N$?�q�/�s�6��p��a����a��J/��M�8��6�ܰ"�*������ɗud"\w���aT(����[��F��U՛����RT�b���n�*��6���O��SJ�.�ij<�v�MT��R\c��5l�sZB>F��<7�;EA��{��E���Ö��1U/�#��d1�a�n.1ě����0�ʾR�h��|�R��Ao�3�m3 ��%�� ���28Q�� ��y��φ���H�To�7�lW>����#i`�q���c����a��� �m,B�-j����݋�'mR1Ήt�>��V��p���s�0IbI�C.���1R�ea�����]H�6�����������4B>��o��](��$B���m�����a�!=���?�B� K�Ǿ+�Ծ"�n���K��*��+��[T#�{�E�J�S����Q�����s�5�:�U�\wĐ�f�3����܆&�)�����I���Ԇw��E T�lrTf6Q|R�h:��[K�� �z��c֧�G�C��%\��_�a��84��HcO�bi��ؖV��7H �)*ģK~Xhչ0��4?�0��� �E<���}3���#���u�?�� ��|g�S�6ꊤ�|�I#Hڛ� �ա��w�X��9��7���Ŀ%�SL��y6č��|�F�a 8���b���$�sק�h���b9RAu7�˨p�Č�_\*w��묦��F ����4D~�f����|(�"m���NK��i�S�>�$d7SlA��/�²����SL��|6N�}���S�˯���g��]6��; �#�.��<���q'Q�1|KQ$�����񛩶"�$r�b:���N8�w@��8$�� �AjfG|~�9F ���Y��ʺ��Bwؒ������M:I岎�G��`s�YV5����6��A �b:�W���G�q%l�����F��H���7�������Fsv7���k�� 403WebShell
403Webshell
Server IP : 103.30.72.248  /  Your IP : 216.73.216.144
Web Server : Microsoft-IIS/10.0
System : Windows NT WIN-CARKG80MF9A 10.0 build 17763 (Windows Server 2019) AMD64
User : IUSR ( 0)
PHP Version : 8.2.7
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  C:/Windows/SysWOW64/WindowsPowerShell/v1.0/Modules/BitLocker/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : C:/Windows/SysWOW64/WindowsPowerShell/v1.0/Modules/BitLocker/BitLocker.psm1
��Import-LocalizedData -BindingVariable stringTable





#########################################################################################

# Copyright (c) Microsoft Corporation

#

# BitLocker PowerShell Module

#

#

#########################################################################################



$E_NOTFOUND = 2147943568

$E_KEYREQUIRED = 2150694941

$E_AUTOUNLOCK_ENABLED = 2150694953

$E_VOLUMEBOUND = 2150694943

$E_FAIL = 2147500037

$TPM_E_DEACTIVATED = 2150105094

$FVE_E_NOT_DECRYPTED = 2150694969

$S_FALSE = 1



$FVE_HARDWARE_TEST_NOT_FAILED_OR_PENDING = 0

$FVE_HARDWARE_TEST_FAILED = 1

$FVE_HARDWARE_TEST_PENDING = 2



$DEFAULT_DISCOVERY_VOLUME_TYPE = "<default>"



$MINIMUM_REQUIRED_RECOVERY_PROTECTORS_WITH_TPM = 2

$MINIMUM_REQUIRED_RECOVERY_PROTECTORS_WITHOUT_TPM = 3



$FVE_CONV_FLAG_DATAONLY = 1



$FVE_FORCE_ENCRYPTION_TYPE_UNSPECIFIED = 0

$FVE_FORCE_ENCRYPTION_TYPE_SOFTWARE = 1

$FVE_FORCE_ENCRYPTION_TYPE_HARDWARE = 2



$FVE_PROVISIONING_MODIFIER_USED_SPACE = 256



#########################################################################################

# Internal Function: Get-ExceptionForHrInternal

#

# Returns the COMException for a given HRESULT

#

# Ex: Get-ExceptionForHrInternal 2147942402

#

# Input: Unsigned integer - Must be a valid HRESULT

#

# Return: COMException class corresponding to the HRESULT.

#########################################################################################

function Get-ExceptionForHrInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [System.UInt32]

          $HrUInt32)

    process

    {

            $HrHexString = [string]::Format("0x{0:X}", $HrUInt32)

            $ExceptionForHr = [System.Runtime.InteropServices.Marshal]::GetExceptionForHR($HrHexString)



            $ExceptionForHr

    }

}



#########################################################################################

# Internal Function: IsNanoPowerShell

#

# Determines if this module is running on Nano PowerShell instead of full PowerShell.

#

# Return: Boolean describing the PowerShell environment.

#

#########################################################################################



function IsNanoPowerShell

{

    if ($PSEdition -eq "Core") 

    { 

        return $true

    }

    else

    {

        return $false

    }

}



#########################################################################################

# Internal Function: Decrypt-SecureStringInternal

#

# Returns a clear text string that had been protected by a SecureString.

#

# Input: SecureString - a password

#

# Return: String contained within the SecureString

#########################################################################################

function Decrypt-SecureStringInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [System.Security.SecureString]

          $SecurePassword

    )

    process

    {

        if (IsNanoPowerShell)

        {

            $intPtr = [System.Security.SecureStringMarshal]::SecureStringToCoTaskMemUnicode($SecurePassword)

            $ClearTextPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($intPtr)

            [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($intPtr)

        }

        else

        {

            $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)

            $ClearTextPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)

            [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)

        }

        return $ClearTextPassword

    }

}



#########################################################################################

# Internal Function: Get-Win32EncryptableVolumeInternal

#

# Returns Win32_EncryptableVolume WMI objects that describes volume [or volumes]

#

# Ex: Get-Win32EncryptableVolumeInternal c: - returns volume information for drive c:

#     Get-Win32EncryptableVolumeInternal    - returns all volumes with volume information. Only for encryptable volumes

#

# Input: String - volume name. Could be: drive letter or volume id or a directory that corresponds to a mounted volume.

#                 This is an optional parameter.

#

# Return: WMI object [Microsoft.Management.Infrastructure.CimInstance] that is a Win32_EncryptableVolume

#########################################################################################

function Get-Win32EncryptableVolumeInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $false)]

          [string]

          $MountPoint)



    process

    {

        Write-Debug "Begin Get-Win32EncryptableVolumeInternal($MountPoint)"



        $Win32EncryptableVolumes = `

            Get-CimInstance `

                -Namespace "root\cimv2\Security\MicrosoftVolumeEncryption" `

                -ClassName Win32_EncryptableVolume



        if (!$Win32EncryptableVolumes)

        {

            Write-Debug "No Win32_EncryptableVolume objects have been returned by Get-CimInstance"

        }



        if (!$MountPoint)

        {

            #

            # MountPoint is not set so all Win32_EncryptableVolumes are returned

            #



            $Win32EncryptableVolume = $null



            Write-Debug "No Filtering of Win32_EncryptableVolumes"

        }

        elseif ($MountPoint -match "^[a-zA-Z]$" -or $MountPoint -match "^[a-zA-Z]:$" -or $MountPoint -match "^[a-zA-Z]:\$")

        {

            #

            # MountPoint is a drive letter followed by an optional colon with an optional slash. ex: "c" or "c:" or "c:\"

            #

            $DriveLetter = $MountPoint.TrimEnd("\")

            if (!$DriveLetter.EndsWith(":"))

            {

                $DriveLetter = $DriveLetter + ":"  # WMI needs to have the colon at the end

            }



            Write-Debug "Filtering Win32_EncryptableVolumes by $DriveLetter"



            $Win32EncryptableVolume = $Win32EncryptableVolumes | where {$_.DriveLetter -eq $DriveLetter}



            #If there is no encryptable volume then fall through and report the error

        }

        elseif ($MountPoint -match "^\\\\\?\\Volume\{[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}\}\\$")

        {

            # 

            # MountPoint is a device id. An example of a valid device id is: \\?\Volume{cb96dd9a-4f54-11e0-8d6c-806e6f6e6963}\

            #

            $DeviceId = $MountPoint



            Write-Debug "Filtering Win32_EncryptableVolumes by $DeviceId"



            $Win32EncryptableVolume = $Win32EncryptableVolumes | where {$_.DeviceId -eq $DeviceId}



            #If there is no encryptable volume then fall through and report the error

        }

        else

        {

            #

            # MountPoint is a directory that is mounted to a volume. Get the volume that it belongs to.

            #



            $MsftVolume = Get-Volume -FilePath $MountPoint



            if (!$MsftVolume)

            {

                Write-Debug "No volume can be found mounted at $MountPoint"

                # Fall through and report error

            }

            else

            {

                $DeviceId = $MsftVolume.UniqueId

 

                Write-Debug "Volume at $MountPoint has Device Id $DeviceId. Filtering Win32_EncryptableVolumes by this Device Id."

            

                $Win32EncryptableVolume = $Win32EncryptableVolumes | where {$_.DeviceID -eq $DeviceId}

            }

        }





        if ($Win32EncryptableVolume)

        {

            $Win32EncryptableVolume

            Write-Debug "End Get-Win32EncryptableVolumeInternal. Return $Win32EncryptableVolume"

        }

        elseif (!$MountPoint -and $Win32EncryptableVolumes)

        {

            # $null for $MountPoint means return all encryptable volumes

            $Win32EncryptableVolumes

            Write-Debug "End Get-Win32EncryptableVolumeInternal. Return $Win32EncryptableVolumes"

        }

        else

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $E_NOTFOUND

            $ErrorMessage = [string]::Format($stringTable.ErrorMountPointNotFound, $MountPoint)

            Write-Error -Exception $ExceptionForHr -Message $ErrorMessage

        }

    }

}



#########################################################################################

# Internal Function: Read-UserSecretInternal

#

# Returns a single SecureString that is a secret [password or pin] entered

# by the user. This secret is confirmed by requiring the user to enter it

# twice and verifying that they are the same.

#

# If the two secrets are not the same then we re-prompt the user for both secrets.

# 

# Ex: Read-UserSecretInternal -Message "Enter Password:" -ConfirmMessage "Confirm Password:" -NotMatchMessage "Passwords do not match. Re-enter"

#

# Input: Message String - Output to user to enter the secret

#        Confirm Message String - Output to user to confirm secret

#        NotMessage Message String - Output to the user if the two secrets 

#                                    do not match

#

# Return: One of the SecureStrings that the user entered.

#########################################################################################

function Read-UserSecretInternal

{

    

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $Message,



          [Parameter(Position = 1, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $ConfirmMessage,



          [Parameter(Position = 2, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $NotMatchMessage)



    process

    {



        #

        # Break out of this loop when the two secrets entered by the user

        # match

        #

        while ($true) 

        {

            Write-Host $Message -NoNewLine

            $Secret1 = Read-Host -AsSecureString

            Write-Host $ConfirmMessage -NoNewLine

            $Secret2 = Read-Host -AsSecureString





            $ClearTextPassword1 = Decrypt-SecureStringInternal $Secret1

            $ClearTextPassword2 = Decrypt-SecureStringInternal $Secret2



            if ($ClearTextPassword1 -eq $ClearTextPassword2)

            {

                break

            }



            #

            # The two secrets don't match so tell the user and ask user again

            #



            Write-Host $NotMatchMessage

        }



        # Clear the clear text password strings.

        $ClearTextPassword1 = ""

        $ClearTextPassword1 = ""



        return $Secret1

    }



}



#########################################################################################

# Internal Function: Get-BitLockerVolumeInternal

#

# Returns a single BitLockerVolume structure that describes a volume

#

# Ex: Get-BitLockerVolumeInternal c: - returns volume information for drive c:

#

# Input: String - volume name. Could be: drive letter or volume id

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume

#########################################################################################

function Get-BitLockerVolumeInternal

{

    

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint)

    process

    {

        Write-Debug "Begin Get-BitLockerVolumeInternal($MountPoint)"



        $FREE_SPACE_WIPE_IN_PROGRESS     = 2

        $FREE_SPACE_WIPE_SUSPENDED       = 3

        $BYTES_IN_GIGABYTE               = 1024*1024*1024



        #######

        # Get Win32_EncryptableVolume

        #######



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        if (!$Win32EncryptableVolume)

        {

            Write-Debug "The following operation failed: Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint"

            return

        }



        #######

        # Get MSFT_Volume associated with Win32_EncryptableVolume.

        # Use Win32_EncryptableVolume.DeviceID

        #######



        $WmiVolumeFilter = "UniqueID = '$($Win32EncryptableVolume.DeviceID.Replace("\", "\\"))'"

        $MsftVolume =  Get-CimInstance MSFT_Volume -NameSpace 'Root\Microsoft\Windows\Storage' -Filter $WmiVolumeFilter

        if (!$MsftVolume)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $E_NOTFOUND

            $ErrorMessage = [string]::Format($stringTable.ErrorVolumeNotFound, $Win32EncryptableVolume.DeviceId)

            Write-Error -Exception $ExceptionForHr -Message $ErrorMessage



            Write-Debug "Filter: $WmiVolumeFilter"

            return

        }



        #

        # This matches WMI .Net's $Win32EncryptableVolume.__SERVER. 

        # MI .Net exposes $Win32EncryptableVolume.CimSystemProperties.ServerName as "localhost"

        #

        $ComputerName = $env:computername 



        #

        # Overwrite the passed in $MountPoint parameter with the the info from Win32_EncryptableVolume

        #

        if ($Win32EncryptableVolume.DriveLetter)

        {

            $MountPoint = $Win32EncryptableVolume.DriveLetter

        }

        else

        {

            $MountPoint = $Win32EncryptableVolume.DeviceID

        }



        #######

        # Get LockStatus. Win32_EncryptableVolume::GetLockStatus

        #######



        $LockStatusResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetLockStatus

        if ($LockStatusResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $LockStatusResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return

        }

        $LockStatus = $LockStatusResult.LockStatus



        Write-Debug "ComputerName: $ComputerName. MountPoint: $MountPoint. LockStatus: $LockStatus"

        

        #######

        # Get EncryptionMethod. Win32_EncryptableVolume::GetEncryptionMethod

        #######



        $EncryptionMethodResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetEncryptionMethod

        if ($EncryptionMethodResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $EncryptionMethodResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return

        }

        $EncryptionMethod = $EncryptionMethodResult.EncryptionMethod



        Write-Debug "EncryptionMethod: $EncryptionMethod"



        #######

        # AutoUnlock. Win32_EncryptableVolume::IsAutoUnlockEnabled

        # This will determine if autounlock is enabled for the volume and what the

        # protector id is. This is relevant only for data volumes.

        # Failure is ok. It means the setting does not apply to this volume.

        #######



        $AutoUnlockEnabledResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName IsAutoUnlockEnabled

        $AutoUnlockKeyProtectorId = $null



        if ($AutoUnlockEnabledResult.ReturnValue -ne 0)

        {

            Write-Debug "Win32EncryptableVolume.IsAutoUnlockEnabled() returned error $AutoUnlockEnabledResult.ReturnValue"

            $AutoUnlockEnabled = $null

        }

        else

        {

            $AutoUnlockEnabled = $AutoUnlockEnabledResult.IsAutoUnlockEnabled

            if ($AutoUnlockEnabled -eq $true)

            {

                $AutoUnlockKeyProtectorId = $AutoUnlockEnabledResult.VolumeKeyProtectorID

            }

        }



        Write-Debug "AutoUnlockEnabled: $AutoUnlockEnabled. AutoUnlockKeyProtectorId: $AutoUnlockKeyProtectorId"



        #######

        # AutoUnlockKeyStored. Win32_EncryptableVolume::IsAutoUnlockKeyStored

        # This will determine if autounlock keys are stored in the volume.

        # This is only applicable to OS volumes.

        # Failure is ok. It means the setting does not apply to this volume.

        #######



        $AutoUnlockKeyStoredResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName IsAutoUnlockKeyStored

        if ($AutoUnlockKeyStoredResult.ReturnValue -ne 0)

        {

            Write-Debug "Win32EncryptableVolume.IsAutoUnlockKeyStored() returned error $AutoUnlockKeyStoredResult.ReturnValue"

            $AutoUnlockKeyStored = $null

        }

        else

        {

            $AutoUnlockKeyStored = $AutoUnlockKeyStoredResult.IsAutoUnlockKeyStored

        }



        Write-Debug "AutoUnlockKeyStored: $AutoUnlockKeyStored"



        #######

        # Get MetaDataVersion. Win32_EncryptableVolume::GetVersion()

        #######



        $MetaDataVersionResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetVersion

        if ($MetaDataVersionResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $MetaDataVersionResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return

        }

        $MetaDataVersion = $MetaDataVersionResult.Version

        Write-Debug "MetaDataVersion: $MetaDataVersion"





        #######

        # Get ConversionStatus, WipingStatus, EncryptionPercentage, WipePercentage.

        # Win32_EncryptableVolume::GetConversionStatus()

        # We make these calls only on unlocked volumes. Otherwise, the values are initialized to $null

        #######



        if ($LockStatus -eq [uint32][Microsoft.BitLocker.Structures.BitLockerVolumeLockStatus]::Unlocked)

        {

            $ConversionStatusResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetConversionStatus

            if ($ConversionStatusResult.ReturnValue -ne 0)

            {

                $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $ConversionStatusResult.ReturnValue

                Write-Error -Exception $ExceptionForHr

                return

            }

            $ConversionStatus      = $ConversionStatusResult.ConversionStatus

            $WipingStatus          = $ConversionStatusResult.WipingStatus

            $EncryptionPercentage  = $ConversionStatusResult.EncryptionPercentage

            $WipePercentage        = $ConversionStatusResult.WipingPercentage

            Write-Debug "ConversionStatus: $ConversionStatus. WipingStatus: $WipingStatus. EncryptionPercentage: $EncryptionPercentage. WipePercentage: $WipePercentage"



        

            if ($ConversionStatus -eq [uint32][Microsoft.BitLocker.Structures.BitLockerVolumeStatus]::FullyEncrypted -and $WipingStatus -eq $FREE_SPACE_WIPE_IN_PROGRESS)

            {

                $VolumeStatus = [Microsoft.BitLocker.Structures.BitLockerVolumeStatus]::FullyEncryptedWipeInProgress

            }

            elseif ($ConversionStatus -eq [uint32][Microsoft.BitLocker.Structures.BitLockerVolumeStatus]::FullyEncryptedWipeInProgress -and $WipingStatus -eq $FREE_SPACE_WIPE_SUSPENDED)  

            {

                $VolumeStatus = [Microsoft.BitLocker.Structures.BitLockerVolumeStatus]::FullyEncryptedWipeSuspended

            }

            else

            {

                $VolumeStatus = $ConversionStatus

            }

        }

        else

        {

            $ConversionStatus      = $null

            $WipingStatus          = $null

            $VolumeStatus          = $null

            $WipePercentage        = $null

            $EncryptionPercentage  = $null

        }



        #######

        # Get ProtectionStatus

        # Win32_EncryptableVolume::GetProtectionStatus()

        #######



        $ProtectionStatusResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetProtectionStatus

        if ($ProtectionStatusResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $ProtectionStatusResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return

        }

        $ProtectionStatus = $ProtectionStatusResult.ProtectionStatus

        Write-Debug "ProtectionStatus: $ProtectionStatus."

        

        #######

        # Get VolumeType [OS, Data] and capacity from MSFT_Volume

        #######



        if ($MsftVolume.DriveLetter -eq $env:SystemDrive[0])

        {

            $VolumeType = [Microsoft.BitLocker.Structures.BitLockerVolumeType]::OperatingSystem

        }

        else

        {

            $VolumeType = [Microsoft.BitLocker.Structures.BitLockerVolumeType]::Data

        }



        $CapacityGB = $MsftVolume.Size / $BYTES_IN_GIGABYTE



        Write-Debug "VolumeType: $VolumeType. CapacityGB: $CapacityGB"



        #######

        # Get list of key protector ids Win32_EncryptableVolume::GetKeyProtectors

        # For each key protector id we do:

        #   - Get key protector type Win32_EncryptableVolume::GetKeyProtectorType

        #   - For Unlocked volumes we also get extra data for external key, numerical password

        #     and public key, and tpm network key.

        #######





        $KeyProtectorIdsResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetKeyProtectors

        if ($KeyProtectorIdsResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $KeyProtectorIdsResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return

        }

        $KeyProtectorIds = $KeyProtectorIdsResult.VolumeKeyProtectorID

        Write-Debug "KeyProtectorIds: $KeyProtectorIds"

        

        [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtector[]]$KeyProtectors = $null

        for ($i=0; $i -lt $KeyProtectorIds.Length; $i++)

        {

            $KeyProtectorId               = $KeyProtectorIds[$i]

            $KeyProtectorTypeResult       = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetKeyProtectorType -Arguments @{VolumeKeyProtectorID = $KeyProtectorId}

            if ($KeyProtectorTypeResult.ReturnValue -ne 0)

            {

                $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $KeyProtectorTypeResult.ReturnValue

                Write-Error -Exception $ExceptionForHr

                return

            }

            $KeyProtectorType             = $KeyProtectorTypeResult.KeyProtectorType



            Write-Debug "KeyProtector[$i] = KeyProtectorId: $KeyProtectorId. KeyProtectorType: $KeyProtectorType"



            $KeyProtectorFileName         = $null

            $KeyProtectorRecoveryPassword = $null

            $KeyProtectorThumbprint       = $null

            $KeyProtectorCertificateType  = $null

            $AutoUnlockProtector          = $null   # true or false only for external key protector type

        



            if ($LockStatus -eq [uint32][Microsoft.BitLocker.Structures.BitLockerVolumeLockStatus]::Unlocked)

            {



                if ($KeyProtectorType -eq [uint32][Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::ExternalKey)

                {

                    $KeyProtectorFileNameResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetExternalKeyFileName -Arguments @{VolumeKeyProtectorID = $keyProtectorId}

                    if ($KeyProtectorFileNameResult.ReturnValue -ne 0)

                    {

                        $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $KeyProtectorFileNameResult.ReturnValue

                        Write-Error -Exception $ExceptionForHr

                        return

                    }

                    $KeyProtectorFileName = $KeyProtectorFileNameResult.FileName



                    if ($AutoUnlockKeyProtectorId -ne $null)

                    {

                        if ($AutoUnlockKeyProtectorId -eq $KeyProtectorId)

                        {

                            $AutoUnlockProtector = $true

                        }

                        else

                        {

                            $AutoUnlockProtector = $false

                        }

                    }  

                    Write-Debug "KeyProtectorFileName: $KeyProtectorFileName. AutoUnlockProtector: $AutoUnlockProtector"



                }

                elseif ($KeyProtectorType -eq [uint32][Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::RecoveryPassword)

                {

                    $KeyProtectorRecoveryPasswordResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetKeyProtectorNumericalPassword -Arguments @{VolumeKeyProtectorID = $keyProtectorId}

                    if ($KeyProtectorRecoveryPasswordResult.ReturnValue -ne 0)

                    {

                        $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $KeyProtectorRecoveryPasswordResult.ReturnValue

                        Write-Error -Exception $ExceptionForHr

                        return

                    }

                    $KeyProtectorRecoveryPassword = $KeyProtectorRecoveryPasswordResult.NumericalPassword

                    Write-Debug "KeyProtectorRecoveryPassword found"

                }

                elseif ($KeyProtectorType -eq [uint32][Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::PublicKey -or $KeyProtectorType -eq [uint32][Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::TpmNetworkKey)

                {

                    $KeyProtectorCertificateResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetKeyProtectorCertificate -Arguments @{VolumeKeyProtectorID = $KeyProtectorId}

                    if ($KeyProtectorCertificateResult.ReturnValue -ne 0)

                    {

                        $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $KeyProtectorCertificateResult.ReturnValue

                        Write-Error -Exception $ExceptionForHr

                        return

                    }

                    $KeyProtectorThumbprint = $KeyProtectorCertificateResult.CertThumbprint

                    $KeyProtectorCertificateType = $KeyProtectorCertificateResult.CertType

                    Write-Debug "KeyProtectorThumbprint: $KeyProtectorThumbprint. KeyProtectorCertificateType: $KeyProtectorCertificateType"

                }



            }



            $KeyProtector = new-object Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtector -argumentlist $KeyProtectorId,$AutoUnlockProtector,$KeyProtectorType,$KeyProtectorFileName,$KeyProtectorRecoveryPassword,$KeyProtectorCertificateType,$KeyProtectorThumbprint

            $KeyProtectors = $KeyProtectors + $KeyProtector

        }

        



        $BitLockerVolume = new-object Microsoft.BitLocker.Structures.BitLockerVolume -argumentlist $ComputerName, $MountPoint, $EncryptionMethod, $AutoUnlockEnabled, $AutoUnlockKeyStored, $MetaDataVersion, $VolumeStatus, $ProtectionStatus, $LockStatus, $EncryptionPercentage, $WipePercentage, $VolumeType, $CapacityGB, $KeyProtectors



        $BitLockerVolume

        Write-Debug "End Get-BitLockerVolumeInternal. Return $BitLockerVolume"

    }

}



#########################################################################################

# Get-BitLockerVolume

#

# Returns BitLockerVolume structures that describes a volume [or volumes]

#

# Ex: Get-BitLockerVolume c: - returns volume information for drive c:

#     Get-BitLockerVolume    - returns volume information for all volumes that are encryptable

#

# Input: String[] - array of volume names. Could be: drive letter or volume id or mounted directory

#                   This is an optional input parameter.

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Get-BitLockerVolume

{



    [CmdletBinding()]

    Param(

          [Parameter(Position = 0, Mandatory = $false, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [string[]]

          $MountPoint)



    process

    {

        Write-Debug "Begin Get-BitLockerVolume($MountPoint)"



        if ($MountPoint)

        {

            $MountPoint | ForEach-Object -process {Get-BitLockerVolumeInternal -MountPoint $_}

        }

        else

        {

            $AllWin32EncryptableVolume = Get-Win32EncryptableVolumeInternal

            $AllWin32EncryptableVolume | ForEach-Object -process { if ($_.DriveLetter) {Get-BitLockerVolumeInternal -MountPoint $_.DriveLetter} else {Get-BitLockerVolumeInternal -MountPoint $_.DeviceId} }

        }

        

        Write-Debug "End Get-BitLockerVolume"

    }



}



#########################################################################################

# Suspend-BitLocker

#

# Returns BitLockerVolume structures that describes the volumes which have been suspended.

# Suspended means that the key protectors have been disabled. The drive contents are still

# encrypted and if encryption or decryption is in progress then this cmdlet will not change

# that. To stop the encryption or decryption process you need to call the WMI method

# PauseConversion.

#

# Input: String[]    - array of volume names. Could be: drive letter or volume id or mounted directory

#        RebootCount - Number of reboots until the volume has its key protectors re-enabled. 0 means 

#                      never enable key protectors automatically after a reboot. You need to Resume-BitLocker.

#                      For data volumes, it doesn't make sense to specify a value; if you do the WMI layer

#                      returns an error. For OS volumes, the default

#                      is determined by the WMI layer which is 1.

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Suspend-BitLocker

{

    [CmdletBinding(SupportsShouldProcess=$true)]



    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $false)]

          [ValidateRange(0,15)]

          [int]

          $RebootCount = -1)



    process

    {

       Write-Debug "Begin Suspend-BitLocker($MountPoint, $RebootCount)"



       #########

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point whose protectors

       # can be disabled then the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #########

       [string[]]$ValidMountPoint = $null



       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                $Win32EncryptableVolume     =  Get-Win32EncryptableVolumeInternal -MountPoint $BitLockerVolumeInternal.MountPoint

                if ($RebootCount -ne -1)

                {

                    $DisableKeyProtectorsResult =  Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName DisableKeyProtectors -Arguments @{DisableCount = [uint32]$RebootCount}

                }

                else

                {

                    $DisableKeyProtectorsResult =  Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName DisableKeyProtectors

                }



                if ($DisableKeyProtectorsResult.ReturnValue -ne 0)

                {

                    $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $DisableKeyProtectorsResult.ReturnValue

                    Write-Error -Exception $ExceptionForHr

                    continue

                }



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }

        } 



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid mount point was provided that can be suspended"

        }



        Write-Debug "End Suspend-BitLocker. Return $BitLockerVolume"

    }

}



#########################################################################################

# Resume-BitLocker

#

# Returns BitLockerVolume structures that describes the volumes which have been resumed.

# Resumed means that the key protectors have been enabled. The drive contents are still

# encrypted and if encryption or decryption is paused then this cmdlet will not change

# that. To resume the encryption or decryption process you need to call the WMI method 

# ResumeConversion.

#

# Input: String[]    - array of volume names. Could be: drive letter or volume id or mounted directory

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Resume-BitLocker

{

    [CmdletBinding(SupportsShouldProcess=$true)]

    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint)

    process

    {

       Write-Debug "Begin Resume-BitLocker($MountPoint)"



       <#

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point whose protectors

       # can be disabled then the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #>

       [string[]]$ValidMountPoint = $null





       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                $Win32EncryptableVolume     =  Get-Win32EncryptableVolumeInternal -MountPoint $BitLockerVolumeInternal.MountPoint

                $EnableKeyProtectorsResult  =  Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName EnableKeyProtectors



                if ($EnableKeyProtectorsResult.ReturnValue -ne 0)

                {

                    $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $EnableKeyProtectorsResult.ReturnValue

                    Write-Error -Exception $ExceptionForHr

                    continue

                }



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }



        } 



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid mount point was provided that can be resumed"

        }





        Write-Debug "End Resume-BitLocker. Return $BitLockerVolume"

    }

}



#########################################################################################

# Lock-BitLocker

#

# Returns BitLockerVolume structures that describes the volumes which have been locked.

# Locked means volume is dismounted and the volume's encryption key is removed from system memory.

# The contents of the volume remain inacessible until it is unlocked.

#

# Input: String[]      - array of volume names. Could be: drive letter or volume id or mounted directory

#        Bool          - ForceDismount flag. If $true the disk is forcefully dismounted

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Lock-BitLocker

{

    [CmdletBinding(SupportsShouldProcess=$true)]

    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint,



          [Parameter(Mandatory = $false)]

          [Alias("fd")]

          [System.Management.Automation.SwitchParameter]

          $ForceDismount = $false)



    process

    {

       Write-Debug "Begin Lock-BitLocker($MountPoint)"



       #########

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point then

       # the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #########

       [string[]]$ValidMountPoint = $null



       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                $Win32EncryptableVolume  =  Get-Win32EncryptableVolumeInternal -MountPoint $BitLockerVolumeInternal.MountPoint

                $LockResult              =  Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName Lock -Arguments @{ForceDismount = $ForceDismount.IsPresent}



                if ($LockResult.ReturnValue -ne 0)

                {

                    $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $LockResult.ReturnValue

                    Write-Error -Exception $ExceptionForHr

                    continue

                }



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }

        } 



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid mount point was provided that can be locked"

        }



        Write-Debug "End Lock-BitLocker. Return $BitLockerVolume"

    }

}



#########################################################################################

# Unlock-PasswordInternal

#

# Returns BitLockerVolume structure that describes the volume after it was unlocked

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#        SecureString     - password to use for unlocking

#

# Return: 0 for success

#########################################################################################

function Unlock-PasswordInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true)]

          [System.Security.SecureString]

          $Password

    )

    process

    {

        Write-Debug "Begin Unlock-PasswordInternal"



        #

        # Convert secure string to cleartext.

        #



        $ClearTextPassword = Decrypt-SecureStringInternal $Password



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        $UnlockResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName UnlockWithPassphrase -Arguments @{PassPhrase = $ClearTextPassword}



        # Clear the clear text password string

        $ClearTextPassword = ""



        if ($UnlockResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $UnlockResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $UnlockResult.ReturnValue

        }



        Write-Debug "End Unlock-PasswordInternal"



        return 0

    }

}



#########################################################################################

# Unlock-RecoveryPasswordInternal

#

# Returns BitLockerVolume structure that describes the volume after it was unlocked

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#        String           - recovery password to use for unlocking

#

# Return: 0 for success

#########################################################################################

function Unlock-RecoveryPasswordInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true)]

          [string]

          $RecoveryPassword

    )

    process

    {

        Write-Debug "Begin Unlock-RecoveryPasswordInternal"



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        $UnlockResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName UnlockWithNumericalPassword -Arguments @{NumericalPassword = $RecoveryPassword}



        if ($UnlockResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $UnlockResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $UnlockResult.ReturnValue

        }



        Write-Debug "End Unlock-RecoveryPasswordInternal"



        return 0

    }

}



#########################################################################################

# Unlock-RecoveryKeyInternal

#

# Returns BitLockerVolume structure that describes the volume after it was unlocked

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#        String           - recovery key to use for unlocking

#

# Return: 0 for success

#########################################################################################

function Unlock-RecoveryKeyInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true)]

          [string]

          $RecoveryKeyPath

    )

    process

    {

        Write-Debug "Begin Unlock-RecoveryKeyInternal"



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint



        $GetExternalKeyFromFileResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetExternalKeyFromFile -Arguments @{PathWithFileName = $RecoveryKeyPath}



        if ($GetExternalKeyFromFileResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $GetExternalKeyFromFileResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $GetExternalKeyFromFileResult.ReturnValue

        }



        $UnlockResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName UnlockWithExternalKey -Arguments @{ExternalKey = $GetExternalKeyFromFileResult.ExternalKey}



        if ($UnlockResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $UnlockResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $UnlockResult.ReturnValue

        }



        Write-Debug "End Unlock-RecoveryKeyInternal"



        return 0

    }

}



#########################################################################################

# Unlock-BitLocker

#

# Returns BitLockerVolume structures that describes the volumes which have been unlocked.

#

# Input: String[]      - array of volume names. Could be: drive letter or volume id or mounted directory

#        Protector     - protector to use for unlocking

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Unlock-BitLocker

{

    [CmdletBinding(SupportsShouldProcess=$true)]

    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint,



          #

          # Password Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="OnlyPasswordParameterSet")]

          [Alias("pw")]

          [System.Security.SecureString]

          $Password,



          #

          # Recovery Password Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="OnlyRecoveryPasswordParameterSet")]

          [ValidateNotNullOrEmpty()]

          [Alias("rp")]

          [String]

          $RecoveryPassword,



          #

          # Recovery Key Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="OnlyRecoveryKeyParameterSet")]

          [ValidateNotNullOrEmpty()]

          [Alias("rk")]

          [String]

          $RecoveryKeyPath,



          #

          # Ad Account Or Group Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="OnlyAdAccountOrGroupParameterSet")]

          [System.Management.Automation.SwitchParameter]

          $AdAccountOrGroup

    )



    process

    {

       Write-Debug "Begin Unlock-BitLocker($MountPoint)"



       #########

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point then

       # the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #########

       [string[]]$ValidMountPoint = $null



       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                if ($PsCmdlet.ParameterSetName -eq "OnlyPasswordParameterSet")

                {

                    $Result = Unlock-PasswordInternal $BitLockerVolumeInternal.MountPoint $Password

                }

                elseif ($PsCmdlet.ParameterSetName -eq "OnlyRecoveryPasswordParameterSet")

                {

                    $Result = Unlock-RecoveryPasswordInternal $BitLockerVolumeInternal.MountPoint $RecoveryPassword

                }

                elseif ($PsCmdlet.ParameterSetName -eq "OnlyRecoveryKeyParameterSet")

                {

                    $Result = Unlock-RecoveryKeyInternal $BitLockerVolumeInternal.MountPoint $RecoveryKeyPath

                }

                elseif ($PsCmdlet.ParameterSetName -eq "OnlyAdAccountOrGroupParameterSet")

                {

                    $Result = Unlock-AdAccountOrGroupInternal $BitLockerVolumeInternal.MountPoint

                }



                if ($Result -ne 0)

                {

                    Write-Debug "Unlock-BitLocker failed for $BitLockerVolumeInternal.MountPoint"

                    continue

                }



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }

        } 



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid mount point was provided that can be unlocked"

        }



        Write-Debug "End Unlock-BitLocker. Return $BitLockerVolume"

    }

}



#########################################################################################

# Add-RecoveryPasswordProtectorInternal

#

# Returns BitLockerVolume structure that describes the volume with the new recovery password protector

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#        RecoveryPassword - recovery password protector to add. Can be empty.

#

# Return: 0 for success

#########################################################################################

function Add-RecoveryPasswordProtectorInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $false)]

          [string]

          $RecoveryPassword,



          [Parameter(Mandatory = $false)]

          [System.Management.Automation.SwitchParameter]

          $SuppressWarningMessage = $false

    )

    process

    {

        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint



        if ($RecoveryPassword -eq "")

        {

            $AddKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ProtectKeyWithNumericalPassword -Arguments @{FriendlyName = $null; NumericalPassword = $null}

        }

        else

        {

            $AddKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ProtectKeyWithNumericalPassword -Arguments @{FriendlyName = $null; NumericalPassword = $RecoveryPassword}

        }



        if ($AddKeyProtectorResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $AddKeyProtectorResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $AddKeyProtectorResult.ReturnValue

        }



        if (!$SuppressWarningMessage)

        {

            $KeyProtectorId = $AddKeyProtectorResult.VolumeKeyProtectorID



            $RecoveryPasswordResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetKeyProtectorNumericalPassword -Arguments @{VolumeKeyProtectorID = $KeyProtectorId}

            if ($RecoveryPasswordResult.ReturnValue -ne 0)

            {

                $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $RecoveryPasswordResult.ReturnValue

                Write-Error -Exception $ExceptionForHr

                return $RecoveryPasswordResult.ReturnValue

            }

            $RecoveryPassword = $RecoveryPasswordResult.NumericalPassword

            Write-Debug "RecoveryPassword added"



            $Message = [string]::Format($stringTable.WarningWriteDownRecoveryPassword, $RecoveryPassword, [Environment]::NewLine)

            Write-Warning $Message

        }



        return 0

    }

}



#########################################################################################

# Add-PasswordProtectorInternal

#

# Adds a passphrase protector to a volume

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#        SecureString     - password

#

# Return: 0 for success

#########################################################################################

function Add-PasswordProtectorInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $false)]

          [System.Security.SecureString]

          $Password

    )

    process

    {

        if ($Password -eq $null)

        {

            $Password = Read-UserSecretInternal -Message $stringTable.PasswordPrompt -ConfirmMessage $stringTable.ConfirmPasswordPrompt -NotMatchMessage $stringTable.NoMatchPassword

        }



        #

        # Convert secure string to cleartext.

        #

        $ClearTextPassword = Decrypt-SecureStringInternal $Password



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        $AddKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ProtectKeyWithPassphrase -Arguments @{FriendlyName = $null; PassPhrase = $ClearTextPassword}



        # Clear the clear text password string

        $ClearTextPassword = ""



        if ($AddKeyProtectorResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $AddKeyProtectorResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $AddKeyProtectorResult.ReturnValue

        }



        return 0

    }

}



#########################################################################################

# Remove-KeyProtectorByTypeInternal

#

# Deletes one key protector of the type specified by $ProtectorType

#

# Input: String - volume name. Could be: drive letter or volume id or mounted directory

#        uint32 - protector type of protector that is to be deleted

#

# Return: 0 for success

#########################################################################################

function Remove-KeyProtectorByTypeInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true)]

          [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]

          $ProtectorType

    )

    process

    {

        #

        # Get key protectors of type $ProtectorType

        #



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        $KeyProtectorIdsResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetKeyProtectors -Arguments @{KeyProtectorType = [uint32]$ProtectorType}



        if ($KeyProtectorIdsResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $KeyProtectorIdsResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $KeyProtectorIdsResult.ReturnValue

        }

        if ($KeyProtectorIdsResult.VolumeKeyProtectorID.Count -ne 1)

        {

            #

            # Return success

            #



            return 0

        }



        $Result = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName DeleteKeyProtector -Arguments @{VolumeKeyProtectorID = $KeyProtectorIdsResult.VolumeKeyProtectorID[0]}

        if ($Result.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        return 0

    }

}



#########################################################################################

# Add-TpmProtectorInternal

#

# Adds a TPM protector to a volume

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#

# Return: 0 for success

#########################################################################################

function Add-TpmProtectorInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint

    )

    process

    {

        Write-Debug "Begin Add-TpmProtectorInternal"



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        $AddKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ProtectKeyWithTPM -Arguments @{FriendlyName = $null; PlatformValidationProfile = $null}



        if ($AddKeyProtectorResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $AddKeyProtectorResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $AddKeyProtectorResult.ReturnValue

        }



        #

        # Delete all other TPM based protectors

        #



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint TpmPin

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint TpmStartupKey

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint TpmPinStartupKey

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        Write-Debug "End Add-TpmProtectorInternal"



        return 0

    }

}



#########################################################################################

# Add-TpmAndPinProtectorInternal

#

# Adds a TPMAndPin protector to a volume

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#        SecureString     - Pin

#

# Return: 0 for success

#########################################################################################

function Add-TpmAndPinProtectorInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $false)]

          [System.Security.SecureString]

          $Pin

    )

    process

    {

        Write-Debug "Begin Add-TpmAndPinProtectorInternal"



        if ($Pin -eq $null)

        {

            $Pin = Read-UserSecretInternal -Message $stringTable.PinPrompt -ConfirmMessage $stringTable.ConfirmPinPrompt -NotMatchMessage $stringTable.NoMatchPin

        }



        #

        # Convert secure string to cleartext.

        #

        $ClearTextPin = Decrypt-SecureStringInternal $Pin



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        $AddKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ProtectKeyWithTPMAndPin -Arguments @{FriendlyName = $null; PlatformValidationProfile = $null; PIN = $ClearTextPin}



        # Clear the clear text pin

        $ClearTextPin = ""



        if ($AddKeyProtectorResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $AddKeyProtectorResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $AddKeyProtectorResult.ReturnValue

        }



        #

        # Delete all other TPM based protectors

        #



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint Tpm

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint TpmStartupKey

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint TpmPinStartupKey

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        Write-Debug "End Add-TpmAndPinProtectorInternal"



        return 0

    }

}



#########################################################################################

# Add-TpmAndStartupKeyProtectorInternal

#

# Adds a TPMAndStartupKey protector to a volume

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#        String           - Startup Key path

#

# Return: 0 for success

#########################################################################################

function Add-TpmAndStartupKeyProtectorInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [String]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true)]

          [String]

          $StartupKeyPath

    )

    process

    {

        Write-Debug "Begin Add-TpmAndStartupKeyProtectorInternal"



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        $AddKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ProtectKeyWithTPMAndStartupKey -Arguments @{ExternalKey = $null; FriendlyName = $null; PlatformValidationProfile = $null}



        if ($AddKeyProtectorResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $AddKeyProtectorResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $AddKeyProtectorResult.ReturnValue

        }



        $SaveExternalKeyResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName SaveExternalKeyToFile -Arguments @{VolumeKeyProtectorID = $AddKeyProtectorResult.VolumeKeyProtectorId; Path = $StartupKeyPath}

        if ($SaveExternalKeyResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $SaveExternalKeyResult.ReturnValue

            Write-Error -Exception $ExceptionForHr



            #

            # Remove previously added protector

            #



            $r = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName DeleteKeyProtector -Arguments @{VolumeKeyProtectorID = $AddKeyProtectorResult.VolumeKeyProtectorID}



            return $SaveExternalKeyResult.ReturnValue

        }



        #

        # Delete all other TPM based protectors

        #



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint Tpm

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint TpmPin

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint TpmPinStartupKey

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        Write-Debug "End Add-TpmAndStartupKeyProtectorInternal"



        return 0

    }

}



#########################################################################################

# Add-TpmAndPinAndStartupKeyProtectorInternal

#

# Adds a TPMAndPinAndStartupKey protector to a volume

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#        SecureString     - Pin

#        String           - Startup Key path

#

# Return: 0 for success

#########################################################################################

function Add-TpmAndPinAndStartupKeyProtectorInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [String]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true)]

          [String]

          $StartupKeyPath,



          [Parameter(Position = 2, Mandatory = $false)]

          [System.Security.SecureString]

          $Pin

    )

    process

    {

        Write-Debug "Begin Add-TpmAndPinAndStartupKeyProtectorInternal"



        if ($Pin -eq $null)

        {

            $Pin = Read-UserSecretInternal -Message $stringTable.PinPrompt -ConfirmMessage $stringTable.ConfirmPinPrompt -NotMatchMessage $stringTable.NoMatchPin

        }



        #

        # Convert secure string to cleartext.

        #

        $ClearTextPin = Decrypt-SecureStringInternal $Pin



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        $AddKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ProtectKeyWithTPMAndPinAndStartupKey -Arguments @{ExternalKey = $null; FriendlyName = $null; PIN = $ClearTextPin; PlatformValidationProfile = $null}



        # Clear the clear text pin

        $ClearTextPin = ""



        if ($AddKeyProtectorResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $AddKeyProtectorResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $AddKeyProtectorResult.ReturnValue

        }



        $SaveExternalKeyResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName SaveExternalKeyToFile -Arguments @{VolumeKeyProtectorID = $AddKeyProtectorResult.VolumeKeyProtectorId; Path = $StartupKeyPath}

        if ($SaveExternalKeyResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $SaveExternalKeyResult.ReturnValue

            Write-Error -Exception $ExceptionForHr



            #

            # Remove previously added protector

            #



            $r = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName DeleteKeyProtector -Arguments @{VolumeKeyProtectorID = $AddKeyProtectorResult.VolumeKeyProtectorID}



            return $SaveExternalKeyResult.ReturnValue

        }



        #

        # Delete all other TPM based protectors

        #



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint Tpm

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint TpmPin

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        $Result = Remove-KeyProtectorByTypeInternal $MountPoint TpmStartupKey

        if ($Result -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $Result

            Write-Error -Exception $ExceptionForHr

            return $Result.ReturnValue

        }



        Write-Debug "End Add-TpmAndPinAndStartupKeyProtectorInternal"



        return 0

    }

}



#########################################################################################

# Add-ExternalKeyProtectorInternal

#

# Adds an ExternalKey protector to a volume (Startup Key, Recovery Key)

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#        String           - External Key path

#

# Return: 0 for success

#########################################################################################

function Add-ExternalKeyProtectorInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [String]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true)]

          [String]

          $ExternalKeyPath

    )

    process

    {

        Write-Debug "Begin Add-ExternalKeyProtectorInternal"



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        $AddKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ProtectKeyWithExternalKey -Arguments @{ExternalKey = $null; FriendlyName = $null}



        if ($AddKeyProtectorResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $AddKeyProtectorResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $AddKeyProtectorResult.ReturnValue

        }



        $SaveExternalKeyResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName SaveExternalKeyToFile -Arguments @{VolumeKeyProtectorID = $AddKeyProtectorResult.VolumeKeyProtectorId; Path = $ExternalKeyPath}

        if ($SaveExternalKeyResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $SaveExternalKeyResult.ReturnValue

            Write-Error -Exception $ExceptionForHr



            #

            # Remove previously added protector

            #



            $r = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName DeleteKeyProtector -Arguments @{VolumeKeyProtectorID = $AddKeyProtectorResult.VolumeKeyProtectorID}



            return $SaveExternalKeyResult.ReturnValue

        }



        Write-Debug "End Add-ExternalKeyProtectorInternal"



        return 0

    }

}



#########################################################################################

# Add-SidProtectorInternal

#

# Adds a SID protector to a volume

#

# Input: String           - volume name. Could be: drive letter or volume id or mounted directory

#        String           - SID

#

# Return: 0 for success

#########################################################################################

function Add-SidProtectorInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [String]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true)]

          [String]

          $Sid,



          [Parameter(Position = 2, Mandatory = $true)]

          [bool]

          $Service

    )

    process

    {

        Write-Debug "Begin Add-SidProtectorInternal"



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint



        $flags = 0

        if ($Service -eq $true)

        {

            $flags = 1 # 1 means FVE_DPAPI_NG_FLAG_UNLOCK_AS_SERVICE_ACCOUNT

        }



        $User = [System.Security.Principal.NTAccount]($Sid)



        try

        {

            $SidStr = $User.Translate([System.Security.Principal.SecurityIdentifier])

        }

        catch

        {

            #

            # Failed to translate, so try to use what the user gave us

            #



            try

            {

                $SidStr = [System.Security.Principal.SecurityIdentifier]($Sid)

            }

            catch

            {

                Write-Error -Exception $_.Exception

                return 1

            }

        }



        $AddKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ProtectKeyWithAdSid -Arguments @{FriendlyName = $null; SidString = $SidStr.Value; Flags = [uint32]$flags}



        if ($AddKeyProtectorResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $AddKeyProtectorResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $AddKeyProtectorResult.ReturnValue

        }



        Write-Debug "End Add-SidProtectorInternal"



        return 0

    }

}



#########################################################################################

# Add-BitLockerKeyProtector

#

# Returns BitLockerVolume structures that describe the volumes with the new protector.

#

# Input: String[]      - array of volume names. Could be: drive letter or volume id or mounted directory

#        KeyProtector  - key protector to add

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Add-BitLockerKeyProtector

{

    [CmdletBinding(SupportsShouldProcess=$true)]

    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint,



          # 

          # Password Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="PasswordProtector")]

          [Alias("pwp")]

          [System.Management.Automation.SwitchParameter]

          $PasswordProtector,



          [Parameter(Mandatory = $false, ParameterSetName="PasswordProtector", Position = 1)]

          [Alias("pw")]

          [System.Security.SecureString]

          $Password,



          # 

          # Recovery Password Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="RecoveryPasswordProtector")]

          [Alias("rpp")]

          [System.Management.Automation.SwitchParameter]

          $RecoveryPasswordProtector,



          [Parameter(Mandatory = $false, ParameterSetName="RecoveryPasswordProtector", Position = 1)]

          [ValidateNotNullOrEmpty()]

          [Alias("rp")]

          [String]

          $RecoveryPassword,



          # 

          # Startup Key Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="StartupKeyProtector")]

          [Alias("skp")]

          [System.Management.Automation.SwitchParameter]

          $StartupKeyProtector,



          [Parameter(Mandatory = $true, ParameterSetName="StartupKeyProtector", Position = 1)]

          [Parameter(Mandatory = $true, ParameterSetName="TpmAndPinAndStartupKeyProtector", Position = 1)]

          [Parameter(Mandatory = $true, ParameterSetName="TpmAndStartupKeyProtector", Position = 1)]

          [Alias("sk")]

          [String]

          $StartupKeyPath,



          # 

          # Sid Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="SidProtector")]

          [Alias("sidp")]

          [System.Management.Automation.SwitchParameter]

          $ADAccountOrGroupProtector,



          [Parameter(Mandatory = $true, ParameterSetName="SidProtector", Position = 1)]

          [Alias("sid")]

          [String]

          $ADAccountOrGroup,



          [Parameter(Mandatory = $false, ParameterSetName="SidProtector")]

          [System.Management.Automation.SwitchParameter]

          $Service,



          # 

          # TPM And Pin And StartupKey Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="TpmAndPinAndStartupKeyProtector")]

          [Alias("tpskp")]

          [System.Management.Automation.SwitchParameter]

          $TpmAndPinAndStartupKeyProtector,



# Defined in the StartupKeyProtector section above

#          [Parameter(Mandatory = $true, ParameterSetName="TpmAndPinAndStartupKeyProtector", Position = 1)]

#          [String]

#          $StartupKeyPath,



          [Parameter(Mandatory = $false, ParameterSetName="TpmAndPinAndStartupKeyProtector", Position = 2)]

          [Parameter(Mandatory = $false, ParameterSetName="TpmAndPinProtector", Position = 1)]

          [Alias("p")]

          [System.Security.SecureString]

          $Pin,





          # 

          # TPM And Pin Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="TpmAndPinProtector")]

          [Alias("tpp")]

          [System.Management.Automation.SwitchParameter]

          $TpmAndPinProtector,



# Defined in TPM And Pin And Startup Key Protector section above

#          [Parameter(Mandatory = $false, ParameterSetName="TpmAndPinProtector", Position = 1)]

#          [System.Security.SecureString]

#          $Pin,





          # 

          # TPM And StartupKey Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="TpmAndStartupKeyProtector")]

          [Alias("tskp")]

          [System.Management.Automation.SwitchParameter]

          $TpmAndStartupKeyProtector,



# Defined in the StartupKeyProtector section above

#          [Parameter(Mandatory = $true, ParameterSetName="TpmAndStartupKeyProtector", Position = 1)]

#          [String]

#          $StartupKeyPath,



          # 

          # TPM Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="TpmProtector")]

          [Alias("tpmp")]

          [System.Management.Automation.SwitchParameter]

          $TpmProtector,



          # 

          # Recovery Key Protector

          #



          [Parameter(Mandatory = $true, ParameterSetName="RecoveryKeyProtector")]

          [Alias("rkp")]

          [System.Management.Automation.SwitchParameter]

          $RecoveryKeyProtector,



          [Parameter(Mandatory = $true, ParameterSetName="RecoveryKeyProtector", Position = 1)]

          [Alias("rk")]

          [String]

          $RecoveryKeyPath

    )

    process

    {

        Write-Debug "Begin Add-BitLockerKeyProtector"



       #########

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point then

       # the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #########

       [string[]]$ValidMountPoint = $null



       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                if ($PsCmdlet.ParameterSetName -eq "RecoveryPasswordProtector")

                {

                    $Result = Add-RecoveryPasswordProtectorInternal $BitLockerVolumeInternal.MountPoint $RecoveryPassword

                }

                elseif ($PsCmdlet.ParameterSetName -eq "PasswordProtector")

                {

                    $Result = Add-PasswordProtectorInternal $BitLockerVolumeInternal.MountPoint $Password

                }

                elseif ($PsCmdlet.ParameterSetName -eq "TpmProtector")

                {

                    $Result = Add-TpmProtectorInternal $BitLockerVolumeInternal.MountPoint

                }

                elseif ($PsCmdlet.ParameterSetName -eq "TpmAndPinProtector")

                {

                    $Result = Add-TpmAndPinProtectorInternal $BitLockerVolumeInternal.MountPoint $Pin

                }

                elseif ($PsCmdlet.ParameterSetName -eq "TpmAndStartupKeyProtector")

                {

                    $Result = Add-TpmAndStartupKeyProtectorInternal $BitLockerVolumeInternal.MountPoint $StartupKeyPath

                }

                elseif ($PsCmdlet.ParameterSetName -eq "TpmAndPinAndStartupKeyProtector")

                {

                    $Result = Add-TpmAndPinAndStartupKeyProtectorInternal $BitLockerVolumeInternal.MountPoint $StartupKeyPath $Pin

                }

                elseif ($PsCmdlet.ParameterSetName -eq "StartupKeyProtector")

                {

                    $Result = Add-ExternalKeyProtectorInternal $BitLockerVolumeInternal.MountPoint $StartupKeyPath

                }

                elseif ($PsCmdlet.ParameterSetName -eq "RecoveryKeyProtector")

                {

                    $Result = Add-ExternalKeyProtectorInternal $BitLockerVolumeInternal.MountPoint $RecoveryKeyPath

                }

                elseif ($PsCmdlet.ParameterSetName -eq "SidProtector")

                {

                    $Result = Add-SidProtectorInternal $BitLockerVolumeInternal.MountPoint $ADAccountOrGroup $Service

                }



                if ($Result -ne 0)

                {

                    Write-Debug "Add-BitLockerKeyProtector failed for $BitLockerVolumeInternal.MountPoint"

                    continue

                }

                

                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }

        } 



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid mount point was provided"

        }



       Write-Debug "End Add-BitLockerKeyProtector"

    }

}



#########################################################################################

# Remove-BitLockerKeyProtector

#

# Returns BitLockerVolume structures that describe the volumes after the protector is deleted.

#

# Input: String[]      - array of volume names. Could be: drive letter or volume id or mounted directory

#        String        - ID of key protector to be removed

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Remove-BitLockerKeyProtector

{

    [CmdletBinding(SupportsShouldProcess=$true)]

    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [Alias("id")]

          [string]

          $KeyProtectorId

    )

    process

    {

       Write-Debug "Begin Remove-BitLockerKeyProtector($MountPoint, $KeyProtectorId)"



       #########

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point then

       # the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #########

       [string[]]$ValidMountPoint = $null



       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                $Win32EncryptableVolume   = Get-Win32EncryptableVolumeInternal -MountPoint $BitLockerVolumeInternal.MountPoint



                $DraKeyProtector = $BitLockerVolumeInternal.KeyProtector | 

                                        where {$_.KeyProtectorId -eq $KeyProtectorId -and

                                               $_.KeyProtectorType -eq [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::PublicKey -and 

                                               [uint32]$_.KeyCertificateType -band [uint32][Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorCertificateTypes]::DataRecoveryAgent -eq [uint32][Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorCertificateTypes]::DataRecoveryAgent}



                if ($DraKeyProtector -ne $null)

                {

                    Write-Error -Message $stringTable.ErrorRemoveDraProtector

                    continue

                }



                $NkpProtector = $BitLockerVolumeInternal.KeyProtector |

                                        where {$_.KeyProtectorId -eq $KeyProtectorId -and

                                               $_.KeyProtectorType -eq [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::TpmNetworkKey}



                if ($NkpProtector -ne $null)

                {

                    Write-Error -Message $stringTable.ErrorRemoveNkpProtector

                    continue

                }



                $DeleteKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName DeleteKeyProtector -Arguments @{VolumeKeyProtectorID = $KeyProtectorId}



                if ($DeleteKeyProtectorResult.ReturnValue -eq $E_KEYREQUIRED)

                {

                    $DisableKeyProtectorsResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName DisableKeyProtectors

                    if ($DisableKeyProtectorsResult.ReturnValue -ne 0)

                    {

                        $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $DisableKeyProtectorsResult

                        Write-Error -Exception $ExceptionForHr

                        continue

                    }



                    $DeleteKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName DeleteKeyProtector -Arguments @{VolumeKeyProtectorID = $KeyProtectorId}

                }



                if ($DeleteKeyProtectorResult.ReturnValue -ne 0)

                {

                    $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $DeleteKeyProtectorResult.ReturnValue

                    if ($DeleteKeyProtectorResult.ReturnValue -eq $E_VOLUMEBOUND)

                    {

                        $ErrorMessage = [string]::Format($stringTable.ErrorVolumeBoundAlready)

                        Write-Error -Exception $ExceptionForHr -Message $ErrorMessage

                    }

                    else

                    {

                        Write-Error -Exception $ExceptionForHr

                    }

                    continue

                }



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }

        } 



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid combination of mountpoint / protector id found"

        }



        Write-Debug "End Remove-BitLockerKeyProtector. Return $BitLockerVolume"

    }

}



#########################################################################################

# Backup-BitLockerKeyProtector

#

# Returns BitLockerVolume structures that describe the volumes after the protector is backed up.

#

# Input: String[]      - array of volume names. Could be: drive letter or volume id or mounted directory

#        String        - ID of key protector to be backed up

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Backup-BitLockerKeyProtector

{

    [CmdletBinding(SupportsShouldProcess=$true)]

    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $KeyProtectorId

    )

    process

    {

       Write-Debug "Begin Backup-BitLockerKeyProtector($MountPoint, $KeyProtectorId)"



       #########

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point then

       # the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #########

       [string[]]$ValidMountPoint = $null



       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                $Win32EncryptableVolume   = Get-Win32EncryptableVolumeInternal -MountPoint $BitLockerVolumeInternal.MountPoint

                $BackupKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName BackupRecoveryInformationToActiveDirectory -Arguments @{VolumeKeyProtectorID = $KeyProtectorId}



                if ($BackupKeyProtectorResult.ReturnValue -eq $S_FALSE)

                {

                    $ErrorMessage = [string]::Format($stringTable.ErrorGroupPolicyDisabledBackup)

                    Write-Error -Message $ErrorMessage

                    continue

                }

                elseif ($BackupKeyProtectorResult.ReturnValue -ne 0)

                {

                    $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $BackupKeyProtectorResult.ReturnValue

                    Write-Error -Exception $ExceptionForHr

                    continue

                }



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }

        } 



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid combination of mountpoint / protector id found"

        }



        Write-Debug "End Backup-BitLockerKeyProtector. Return $BitLockerVolume"

    }

}



#########################################################################################

# BackupToAAD-BitLockerKeyProtector

#

# Returns BitLockerVolume structures that describe the volumes after the protector is backed up.

#

# Input: String[]      - array of volume names. Could be: drive letter or volume id or mounted directory

#        String        - ID of key protector to be backed up

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function BackupToAAD-BitLockerKeyProtector

{

    [CmdletBinding(SupportsShouldProcess=$true)]

    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint,



          [Parameter(Position = 1, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $KeyProtectorId

    )

    process

    {

       Write-Debug "Begin BackupToAAD-BitLockerKeyProtector($MountPoint, $KeyProtectorId)"



       #########

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point then

       # the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #########

       [string[]]$ValidMountPoint = $null



       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                $Win32EncryptableVolume   = Get-Win32EncryptableVolumeInternal -MountPoint $BitLockerVolumeInternal.MountPoint

                $BackupKeyProtectorResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName BackupRecoveryInformationToCloudDomain -Arguments @{VolumeKeyProtectorID = $KeyProtectorId}



                if ($BackupKeyProtectorResult.ReturnValue -ne 0)

                {

                    $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $BackupKeyProtectorResult.ReturnValue

                    Write-Error -Exception $ExceptionForHr

                    continue

                }



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }

        } 



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid combination of mountpoint / protector id found"

        }



        Write-Debug "End BackupToAAD-BitLockerKeyProtector. Return $BitLockerVolume"

    }

}



#########################################################################################

# Enable-BitLockerAutoUnlock

#

# Returns BitLockerVolume structures that describes the volumes which have auto unlock enabled.

#

# Input: String[]    - array of volume names. Could be: drive letter or volume id or mounted directory

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Enable-BitLockerAutoUnlock

{

    [CmdletBinding(SupportsShouldProcess=$true)]

    Param(     

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint)



    process

    {

       Write-Debug "Begin Enable-BitLockerAutoUnlock($MountPoint)"



       #########

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point that can

       # have auto unlock enabled then the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #########

       [string[]]$ValidMountPoint = $null



       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                $Win32EncryptableVolume     = Get-Win32EncryptableVolumeInternal -MountPoint $BitLockerVolumeInternal.MountPoint

                

                $IsAutoUnlockEnabledResult  = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName IsAutoUnlockEnabled

            

                if ($IsAutoUnlockEnabledResult.ReturnValue -ne 0)

                {

                    $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $IsAutoUnlockEnabledResult.ReturnValue

                    Write-Error -Exception $ExceptionForHr

                    continue

                }



                if ($IsAutoUnlockEnabledResult.IsAutoUnlockEnabled -eq $false)

                {

                    $ProtectKeyWithExternalKeyResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ProtectKeyWithExternalKey

                    if ($ProtectKeyWithExternalKeyResult.ReturnValue -ne 0)

                    {

                        $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $ProtectKeyWithExternalKeyResult.ReturnValue

                        Write-Error -Exception $ExceptionForHr

                        continue

                    }



                    Write-Debug ("Added Protector: " + $ProtectKeyWithExternalKeyResult.VolumeKeyProtectorID)



                    $EnableAutoUnlockResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName EnableAutoUnlock -Arguments @{VolumeKeyProtectorID = $ProtectKeyWithExternalKeyResult.VolumeKeyProtectorID}

                    if ($EnableAutoUnlockResult.ReturnValue -ne 0)

                    {

                        $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $EnableAutoUnlockResult.ReturnValue

                        Write-Error -Exception $ExceptionForHr

                        continue

                    }

                }



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }



        } 



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid mount point was provided that can have auto unlock enabled"

        }





        Write-Debug "End Enable-BitLockerAutoUnlock. Return $BitLockerVolume"

    }

}







#########################################################################################

# Disable-BitLockerAutoUnlock

#

# Returns BitLockerVolume structures that describes the volumes which have auto unlock disabled.

#

# Input: String[]    - array of volume names. Could be: drive letter or volume id or mounted directory

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Disable-BitLockerAutoUnlock

{

    [CmdletBinding(SupportsShouldProcess=$true)]

    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint)



    process

    {

       Write-Debug "Begin Disable-BitLockerAutoUnlock($MountPoint)"



       #########

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point that can

       # have auto unlock enabled then the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #########

       [string[]]$ValidMountPoint = $null



       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                $Win32EncryptableVolume     = Get-Win32EncryptableVolumeInternal -MountPoint $BitLockerVolumeInternal.MountPoint



                $IsAutoUnlockEnabledResult  = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName IsAutoUnlockEnabled



                if ($IsAutoUnlockEnabledResult.ReturnValue -ne 0)

                {

                    $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $IsAutoUnlockEnabledResult.ReturnValue

                    Write-Error -Exception $ExceptionForHr

                    continue

                }



                if ($IsAutoUnlockEnabledResult.IsAutoUnlockEnabled -eq $true)

                {



                    $DisableAutoUnlockResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName DisableAutoUnlock

                    if ($DisableAutoUnlockResult.ReturnValue -ne 0)

                    {

                        $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $DisableAutoUnlockResult.ReturnValue

                        Write-Error -Exception $ExceptionForHr

                        continue

                    }

                }



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }



        }



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid mount point was provided that can have auto unlock enabled"

        }





        Write-Debug "End Disable-BitLockerAutoUnlock. Return $BitLockerVolume"

    }

}





#########################################################################################

# Disable-BitLocker

#

# Returns BitLockerVolume structures that describe the volumes which have been disabled.

#

# Input: String[]    - array of volume names. Could be: drive letter or volume id or mounted directory

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Disable-BitLocker

{

    [CmdletBinding(SupportsShouldProcess=$true)]

    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint)



    process

    {

       Write-Debug "Begin Disable-BitLocker($MountPoint)"



       #########

       # ValidMountPoint is a subset of the elements of MountPoint array.

       # If MountPoint array contains an element that is not a valid mount point that can

       # have auto unlock enabled then the mount point is not part of ValidMountPoint

       # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

       #

       # If "-whatif" is used then ValidMountPoint is always $null

       #########

       [string[]]$ValidMountPoint = $null



       for($i=0; $i -lt $MountPoint.Count; $i++)

       {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if (!$BitLockerVolumeInternal)

            {

                $m = $MountPoint[$i]

                Write-Debug "The following operation failed: Get-BitLockerVolumeInternal -MountPoint $m"

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                $Win32EncryptableVolume      = Get-Win32EncryptableVolumeInternal -MountPoint $BitLockerVolumeInternal.MountPoint



                if ($BitLockerVolumeInternal.VolumeType -eq [Microsoft.BitLocker.Structures.BitLockerVolumeType]::OperatingSystem)

                {

                    $IsAutoUnlockKeyStoredResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName IsAutoUnlockKeyStored

                

                    if ($IsAutoUnlockKeyStoredResult.ReturnValue -ne 0)

                    {

                        $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $IsAutoUnlockKeyStoredResult.ReturnValue

                        Write-Error -Exception $ExceptionForHr

                        continue

                    }



                    if ($IsAutoUnlockKeyStoredResult.IsAutoUnlockKeyStored -eq $true)

                    {

                        $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $E_AUTOUNLOCK_ENABLED

                        Write-Error -Exception $ExceptionForHr



                        continue

                    }

                }



                $DecryptResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName Decrypt

                if ($DecryptResult.ReturnValue -ne 0)

                {

                    $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $DecryptResult.ReturnValue

                    Write-Error -Exception $ExceptionForHr

                    continue

                }



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]

            }



        }



        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid mount point was provided that can be decrypted"

        }





        Write-Debug "End Disable-BitLocker. Return $BitLockerVolume"

    }

}







#########################################################################################

# Clear-BitLockerAutoUnlock

#

# Returns BitLockerVolume structure that describes the OS volume which has had auto unlock

# keys cleared.

#

# Input: None

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Clear-BitLockerAutoUnlock

{

    [CmdletBinding()]

    Param()

    process

    {

        Write-Debug "Begin Clear-BitLockerAutoUnlock."



        $OsBitLockerVolume = Get-BitLockerVolume | where {$_.VolumeType -eq [Microsoft.BitLocker.Structures.BitLockerVolumeType]::OperatingSystem}



        if ($OsBitLockerVolume -eq $null)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $E_NOTFOUND

            $ErrorMessage = [string]::Format($stringTable.ErrorOperatingSystemMountPointNotFound)

            Write-Error -Exception $ExceptionForHr -Message $ErrorMessage



        }

        Write-Debug "Operating system volume to operate on: $OsBitLockerVolume."



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $OsBitLockerVolume.MountPoint



        $ClearKeysResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName ClearAllAutoUnlockKeys

            

        if ($ClearKeysResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $ClearKeysResult.ReturnValue

            Write-Error -Exception $ExceptionForHr



            $OsBitLockerVolume = $null

        }

        else

        {

            #

            # Since we modified the OS Volume by clearing all auto unlock keys, we should

            # get a fresh BitLockerVolume

            #

            $OsBitLockerVolume = Get-BitLockerVolume $OsBitLockerVolume

        }



        $OsBitLockerVolume



        Write-Debug "End Clear-BitLockerAutoUnlock. Return $OsBitLockerVolume"

    }

}





#########################################################################################

# Unlock-AdAccountOrGroupInternal

#

# Returns BitLockerVolume structure that describes an unlocked volume. The volume is unlocked

# based on the current user/machine token.

#

# Input: MountPoint

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume

#########################################################################################

function Unlock-AdAccountOrGroupInternal

{

    Param(

          [Parameter(Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint)



    process

    {

        Write-Debug "Begin Unlock-AdAccountOrGroupInternal($MountPoint)"



        $BitLockerVolume        = $null

        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint



        $UnlockWithAdSidResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName UnlockWithAdSid



        if ($UnlockWithAdSidResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $UnlockWithAdSidResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $UnlockWithAdSidResult.ReturnValue

        }



        return 0

        Write-Debug "End Unlock-AdAccountOrGroupInternal. Return $BitLockerVolume"

    }

}



#########################################################################################

# Test-SystemEntropyForBitLocker

#

# Returns true or false

#

# Input: None

#

# Return: $true or $false

#########################################################################################

function Test-SystemEntropyForBitLockerInternal

{

    process

    {

        Write-Debug "Start Test-SystemEntropyForBitLockerInternal"



        $IsWinPe = $false



        $RegistyItem = Get-Item HKLM:\SYSTEM\CurrentControlSet\Control\MiniNT -ErrorAction SilentlyContinue



        if ($RegistryItem -eq $null)

        {

            return $true

        }



        $IsWinPe = $true

        Write-Debug "WinPe: $IsWinPe"



        $Win32Tpm = Get-CimInstance -ClassName Win32_Tpm -Namespace "root\CIMV2\Security\MicrosoftTpm"



        if ($Win32Tpm -eq $null)

        {

            Write-Debug "Tpm WMI object could not not be created"

            return $false

        }





        $IsEnabled              = $false

        $IsActivated            = $false



        $IsEnabledResult = Invoke-CimMethod -InputObject $Win32Tpm -MethodName IsEnabled

        if ($IsEnabledResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $IsEnabledResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $false

        }

        else

        {

            $IsEnabled = $IsEnabledResult.IsEnabled

        }



        $IsActivatedResult = Invoke-CimMethod -InputObject $Win32Tpm -MethodName IsActivated

        if ($IsActivatedResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $IsActivatedResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $false

        }

        else

        {

            $IsActivated = $IsActivatedResult.IsActivated

        }



        Write-Debug "End Test-SystemEntropyForBitLockerInternal. IsEnabled: $IsEnabled   IsActivated: $IsActivated"

        return $IsEnabled -and $IsActivated

    }

}





#########################################################################################

# Test-TpmProtectorNeededInternal

#

# Returns true or false

#

# Input: None

#

# Return: $true or $false

#########################################################################################

function Test-TpmProtectorNeededInternal

{

    Param(

          [Parameter(Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,



          [Parameter(Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $ParameterSetNameFromEnableBitLocker)



    process

    {

        Write-Debug "Begin Test-TpmProtectorNeededInternal"



        $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint

        if ($BitLockerVolumeInternal -eq $false)

        {

            Write-Debug "End Test-TpmProtectorNeededInternal. Return $false. BitLockerVolume not valid"

            return $false

        }



        if ($BitLockerVolumeInternal.VolumeType -ne [Microsoft.BitLocker.Structures.BitLockerVolumeType]::OperatingSystem)

        {

            Write-Debug "End Test-TpmProtectorNeededInternal. Return $false. BitLockerVolume is not an OS volume"

            return $false

        }



        $DoesPasswordProtectorExist = $BitLockerVolumeInternal.KeyProtector | where-object {$_.KeyProtectorType -eq [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::Password}

        $IsTpmReady = Test-TpmForBitLockerInternal



        if ($IsTpmReady -eq $true)

        {

            $AnyTpmKeyProtectorType   = [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::Tpm,

                                        [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::TpmNetworkKey,

                                        [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::TpmPin,

                                        [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::TpmPinStartupKey,

                                        [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::TpmStartupKey



            $DoesAnyTpmProtectorExist = $BitLockerVolumeInternal.KeyProtector | where-object {$AnyTpmKeyProtectorType -contains $_.KeyProtectorType}



            #

            # Check if we don't have the following:

            #  -  Password protector

            #  -  ANY Tpm protector

            #  -  User trying to add a password protector

            #  -  User trying to add ANY Tpm protector

            #

            if ($DoesPasswordProtectorExist -eq $null                                       -and

                $DoesAnyTpmProtectorExist -eq $null                                         -and

                $ParameterSetNameFromEnableBitLocker -ne "PasswordProtector"                -and

                $ParameterSetNameFromEnableBitLocker -ne "TpmProtector"                     -and

                $ParameterSetNameFromEnableBitLocker -ne "TpmAndStartupKeyProtector"        -and

                $ParameterSetNameFromEnableBitLocker -ne "TpmAndPinProtector"               -and

                $ParameterSetNameFromEnableBitLocker -ne "TpmAndPinAndStartupKeyProtector")

            {

                 Write-Debug "End Test-TpmProtectorNeededInternal. Return $true"

                 return $true

            }



         }



        return $false

        Write-Debug "End Test-TpmProtectorNeededInternal. Return $false"

    }



}





#########################################################################################

# Test-TpmForBitLockerInternal

#

# Returns true or false

#

# Input: None

#

# Return: $true or $false

#########################################################################################

function Test-TpmForBitLockerInternal

{

    process

    {

        Write-Debug "Begin Test-TpmForBitLockerInternal"



        $IsEnabled              = $false

        $IsOwned                = $false

        $IsActivated            = $false

        $IsSrkAuthCompatible    = $false



        $Win32Tpm = Get-CimInstance -ClassName Win32_Tpm -Namespace "root\CIMV2\Security\MicrosoftTpm"



        if ($Win32Tpm -eq $null)

        {

            Write-Debug "Tpm WMI object could not not be created"

            return $false

        }



        $IsEnabledResult = Invoke-CimMethod -InputObject $Win32Tpm -MethodName IsEnabled

        if ($IsEnabledResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $IsEnabledResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $false

         }

        else

        {

            $IsEnabled = $IsEnabledResult.IsEnabled

        }



        $IsOwnedResult = Invoke-CimMethod -InputObject $Win32Tpm -MethodName IsOwned

        if ($IsOwnedResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $IsOwnedResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $false

        }

        else

        {

            $IsOwned = $IsOwnedResult.IsOwned

        }



        $IsActivatedResult = Invoke-CimMethod -InputObject $Win32Tpm -MethodName IsActivated

        if ($IsActivatedResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $IsActivatedResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $false

        }

        else

        {

            $IsActivated = $IsActivatedResult.IsActivated

        }



        $IsSrkAuthCompatibleResult = Invoke-CimMethod -InputObject $Win32Tpm -MethodName IsSrkAuthCompatible

        if ($IsSrkAuthCompatibleResult.ReturnValue -ne 0)

        {

            $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $IsSrkAuthCompatibleResult.ReturnValue

            Write-Error -Exception $ExceptionForHr

            return $false

        }

        else

        {

            $IsSrkAuthCompatible = $IsSrkAuthCompatibleResult.IsSrkAuthCompatible

        }





        Write-Debug "End Test-TpmForBitLockerInternal. IsEnabled: $IsEnabled   IsOwned: $IsOwned    IsActivated: $IsActivated    IsSrkAuthCompatible: $IsSrkAuthCompatible"



        return $IsEnabled -and $IsOwned -and $IsActivated -and $IsSrkAuthCompatible

    }

}



function Enable-BitLockerInternal

{

    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,



          [Parameter(Mandatory = $false)]

          [Microsoft.BitLocker.Structures.BitLockerVolumeEncryptionMethodOnEnable]

          $EncryptionMethod,



          [Parameter(Mandatory = $true)]

          [bool]

          $SkipHardwareTest,



          [Parameter(Mandatory = $true)]

          [bool]

          $UsedSpaceOnly)



    process

    {

        Write-Debug "Begin Enable-BitLockerInternal. MountPoint: $MountPoint   EncryptionMethod: $EncryptionMethod   SkipHardwareTest: $SkipHardwareTest    UsedSpaceOnly: $UsedSpaceOnly"



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        if ($Win32EncryptableVolume -eq $null)

        {

            Write-Debug "Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint returned null"

            return

        }



        $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint

        if ($BitLockerVolumeInternal -eq $null)

        {

            Write-Debug "Get-BitLockerVolumeInternal -MountPoint $MountPoint returned null"

            return

        }



        $EncryptionFlags = 0

        if ($UsedSpaceOnly -eq $true)

        {

            $EncryptionFlags = $FVE_CONV_FLAG_DATAONLY

        }





        $IntegerEncryptionMethod = 0 # None which means WMI layer picks encryption method

        if ($EncryptionMethod -ne $null)

        {

            [int]$IntegerEncryptionMethod = $EncryptionMethod

        }





        if ($SkipHardwareTest -eq $true)

        {

            $EncryptResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName Encrypt -Arguments @{EncryptionMethod = [uint32]$IntegerEncryptionMethod; EncryptionFlags = [uint32]$EncryptionFlags}

            if ($EncryptResult.ReturnValue -ne 0)

            {

                $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $EncryptResult.ReturnValue

                Write-Error -Exception $ExceptionForHr

                return

            }

        }

        else

        {

            $EncryptResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName EncryptAfterHardwareTest -Arguments @{EncryptionMethod = [uint32]$IntegerEncryptionMethod; EncryptionFlags = [uint32]$EncryptionFlags}

            if ($EncryptResult.ReturnValue -ne 0)

            {

                $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $EncryptResult.ReturnValue

                Write-Error -Exception $ExceptionForHr

                return

            }

        }



        $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint

        $BitLockerVolumeInternal

        Write-Debug "End Enable-BitLockerInternal. BitLockerVolumeInternal: $BitLockerVolumeInternal"

    }

}



#########################################################################################

#

#########################################################################################

function Show-BitLockerRequiredActionsInternal

{

    Param(

          [Parameter(Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,



          [Parameter(Mandatory = $true)]

          [bool]

          $SkipHardwareTest)



    process

    {

        Write-Debug "Begin Show-BitLockerRequiredActionsInternal. MountPoint: $MountPoint   SkipHardwareTest: $SkipHardwareTest"





        $HardwareTestStatus = $FVE_HARDWARE_TEST_NOT_FAILED_OR_PENDING

        $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint



        if ($BitLockerVolumeInternal -eq $null)

        {

            Write-Debug "Get-BitLockerVolumeInternal -MountPoint $MountPoint returned null"

            return

        }



        $AnyExternalKeyProtectorType = [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::ExternalKey,

                                       [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::TpmAndExternalKey,

                                       [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::TpmAndPinAndExternalKey



        $RecoveryKeyProtector    = $BitLockerVolumeInternal.KeyProtector | Where {$_.KeyProtectorType -eq [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::RecoveryPassword} | Select-Object -First 1

        $AnyExternalKeyProtector = $BitLockerVolumeInternal.KeyProtector | Where {$AnyExternalKeyProtectorType -contains $_.KeyProtectorType} | Select-Object -First 1





        if ($SkipHardwareTest -eq $false)

        {

            $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

            if ($Win32EncryptableVolume -eq $null)

            {

                Write-Debug "Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint returned null"

                return

            }



            $HardwareTestStatusResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName GetHardwareTestStatus

            if ($HardwareTestStatusResult.ReturnValue -ne 0)

            {

                $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $HardwareTestStatusResult.ReturnValue

                Write-Error -Exception $ExceptionForHr

                return

            }



            $HardwareTestStatus = $HardwareTestStatusResult.TestStatus

        }



        if ($HardwareTestStatus -eq $FVE_HARDWARE_TEST_NOT_FAILED_OR_PENDING -and

            $RecoveryKeyProtector -eq $null)

        {

            Write-Debug "End Show-BitLockerRequiredActionsInternal. HardwareTestStatus is not failed or pending"

            return   

        }







        if ($RecoveryKeyProtector -ne $null    -and 

            $HardwareTestStatus -eq $FVE_HARDWARE_TEST_NOT_FAILED_OR_PENDING)

        {

            $Message = [string]::Format($stringTable.WarningWriteDownRecoveryPassword, $RecoveryKeyProtector.RecoveryPassword, [Environment]::NewLine)

            Write-Warning $Message

        }

        elseif ($RecoveryKeyProtector -ne $null    -and 

            $AnyExternalKeyProtector -ne $null -and 

            $HardwareTestStatus -eq $FVE_HARDWARE_TEST_PENDING)

        {

            $Message = [string]::Format($stringTable.WarningWriteDownRecoveryPasswordInsertExternalKeyRestart, $RecoveryKeyProtector.RecoveryPassword, [Environment]::NewLine)

            Write-Warning $Message

        }

        elseif ($RecoveryKeyProtector -eq $null     -and

                 $AnyExternalKeyProtector -ne $null -and 

                 $HardwareTestStatus -eq $FVE_HARDWARE_TEST_PENDING)

        {

            $Message = [string]::Format($stringTable.WarningInsertExternalKeyRestart, [Environment]::NewLine)

            Write-Warning $Message

        }

        elseif ($RecoveryKeyProtector -ne $null     -and

                 $AnyExternalKeyProtector -eq $null -and 

                 $HardwareTestStatus -eq $FVE_HARDWARE_TEST_PENDING)

        {

            $Message = [string]::Format($stringTable.WarningWriteDownRecoveryPasswordRestart, $RecoveryKeyProtector.RecoveryPassword, [Environment]::NewLine)

            Write-Warning $Message

        }      

        elseif ($RecoveryKeyProtector -eq $null     -and

                 $AnyExternalKeyProtector -eq $null -and 

                 $HardwareTestStatus -eq $FVE_HARDWARE_TEST_PENDING)

        {

            $Message = [string]::Format($stringTable.WarningRestart, [Environment]::NewLine)

            Write-Warning $Message

        }

        elseif ($HardwareTestStatus -eq $FVE_HARDWARE_TEST_FAILED)

        {

            $Message = [string]::Format($StringTable.WarningHardwareTestFailed, [Environment]::NewLine)

            Write-Warning $Message

        }



    }

}



#########################################################################################

#

#########################################################################################

function Get-RecoveryKeyProtectorsCountInternal

{

    Param(

          [Parameter(Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint)



    process

    {

        $RecoveryKeyProtectorTypes = [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::PublicKey,

                                     [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::Sid,

                                     [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::ExternalKey,

                                     [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::Password,

                                     [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::RecoveryPassword



        [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtector[]] $KeyProtectors = (Get-BitLockerVolumeInternal -MountPoint $MountPoint).KeyProtector | where {$RecoveryKeyProtectorTypes -contains $_.KeyProtectorType}

        if ($KeyProtectors -eq $null)

        {

            return 0

        }



        return $KeyProtectors.Count

    }

}



#########################################################################################

#

#########################################################################################



function Set-BitLockerVolumeInternal

{

    Param(

          [Parameter(Mandatory = $true)]

          [ValidateNotNullOrEmpty()]

          [string]

          $MountPoint,

      

          [Parameter(Mandatory = $true)]

          [ValidateRange(0,2)] #[($FVE_FORCE_ENCRYPTION_TYPE_UNSPECIFIED,$FVE_FORCE_ENCRYPTION_TYPE_HARDWARE)]

          [int]

          $ForceEncryptionType,



          [Parameter(Mandatory = $true)]

          [bool]

          $UsedSpaceOnly)



    process

    {

        [int]$InitializationFlags = $ForceEncryptionType



        $Win32EncryptableVolume = Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint

        if ($Win32EncryptableVolume -eq $null)

        {

            Write-Debug "Get-Win32EncryptableVolumeInternal -MountPoint $MountPoint returned null"

            return $null

        }



        if ($UsedSpaceOnly -eq $true)

        {

            $InitializationFlags += $FVE_PROVISIONING_MODIFIER_USED_SPACE;

        }



        $PrepareVolumeResult = Invoke-CimMethod -InputObject $Win32EncryptableVolume -MethodName PrepareVolumeEx -Arguments @{DiscoveryVolumeType = $DEFAULT_DISCOVERY_VOLUME_TYPE; InitializationFlags = [uint32]$InitializationFlags}

        if ($PrepareVolumeResult.ReturnValue -ne 0)

        {

            if (($PrepareVolumeResult.ReturnValue -ne $FVE_E_NOT_DECRYPTED) -or

                (($InitializationFlags -ne 0) -and

                 ($InitializationFlags -ne $FVE_PROVISIONING_MODIFIER_USED_SPACE)))

            {

                #

                # The volume may have been previously implicitly initialized

                # through adding protectors. So we should not fail unless we

                # were passing some explicit initialization flags.

                # We also allow remapping on used-space flag because we are

                # going to pass used-space flag later when starting conversion.

                #

                $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $PrepareVolumeResult.ReturnValue

                Write-Error -Exception $ExceptionForHr

                return $null

            }

        }



        Get-BitLockerVolumeInternal -MountPoint $MountPoint

    }

}



#########################################################################################

# Enable-BitLocker

#

# Returns BitLockerVolume structures that describes volumes with bitlocker enabled. 

#

# Input: String[]    - array of volume names. Could be: drive letter or volume id or mounted directory

#

# Return: Microsoft.BitLocker.Structures.BitLockerVolume[]

#########################################################################################



#.ExternalHelp Bitlocker.psm1-help.xml

function Enable-BitLocker

{

    [CmdletBinding(SupportsShouldProcess=$true)]



    Param(

          [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]

          [ValidateNotNullOrEmpty()]

          [string[]]

          $MountPoint,



          [Parameter(Mandatory = $false)]

          [Microsoft.BitLocker.Structures.BitLockerVolumeEncryptionMethodOnEnable]

          $EncryptionMethod,



          [Parameter(Mandatory = $false)]

          [System.Management.Automation.SwitchParameter]

          $HardwareEncryption = $false,



          [Parameter(Mandatory = $false)]

          [System.Management.Automation.SwitchParameter]

          [Alias("s")]

          $SkipHardwareTest = $false,



          [Parameter(Mandatory = $false)]

          [System.Management.Automation.SwitchParameter]

          [Alias("qe")]

          $UsedSpaceOnly = $false,



          # 

          # Password Protector 

          #



          [Parameter(Mandatory = $true, ParameterSetName="PasswordProtector")]

          [Alias("pwp")]

          [System.Management.Automation.SwitchParameter]

          $PasswordProtector = $false,



          [Parameter(Mandatory = $false, ParameterSetName="PasswordProtector", Position = 1)]

          [Alias("pw")]

          [System.Security.SecureString]

          $Password,



          # 

          # Recovery Password Protector 

          #



          [Parameter(Mandatory = $true, ParameterSetName="RecoveryPasswordProtector")]

          [Alias("rpp")]

          [System.Management.Automation.SwitchParameter]

          $RecoveryPasswordProtector = $false,



          [Parameter(Mandatory = $false, ParameterSetName="RecoveryPasswordProtector", Position = 1)]

          [ValidateNotNullOrEmpty()]

          [Alias("rp")]

          [String]

          $RecoveryPassword,



          # 

          # Startup Key Protector 

          #



          [Parameter(Mandatory = $true, ParameterSetName="StartupKeyProtector")]

          [Alias("skp")]

          [System.Management.Automation.SwitchParameter]

          $StartupKeyProtector = $false,



          [Parameter(Mandatory = $true, ParameterSetName="StartupKeyProtector", Position = 1)]

          [Parameter(Mandatory = $true, ParameterSetName="TpmAndPinAndStartupKeyProtector", Position = 1)]

          [Parameter(Mandatory = $true, ParameterSetName="TpmAndStartupKeyProtector", Position = 1)]

          [Alias("sk")]

          [String]

          $StartupKeyPath,



          # 

          # Active Directory Account Or Group Protector 

          #



          [Parameter(Mandatory = $true, ParameterSetName="AdAccountOrGroupProtector")]

          [Alias("sidp")]

          [System.Management.Automation.SwitchParameter]

          $AdAccountOrGroupProtector = $false,



          [Parameter(Mandatory = $false, ParameterSetName="AdAccountOrGroupProtector")]

          [System.Management.Automation.SwitchParameter]

          $Service = $false,



          [Parameter(Mandatory = $true, ParameterSetName="AdAccountOrGroupProtector", Position = 1)]

          [Alias("sid")]

          [String]

          $AdAccountOrGroup,



          # 

          # TPM And Pin And StartupKey Protector 

          #



          [Parameter(Mandatory = $true, ParameterSetName="TpmAndPinAndStartupKeyProtector")]

          [Alias("tpskp")]

          [System.Management.Automation.SwitchParameter]

          $TpmAndPinAndStartupKeyProtector = $false,



          # Defined in the StartupKeyProtector section above

          #          [Parameter(Mandatory = $true, ParameterSetName="TpmAndPinAndStartupKeyProtector", Position = 1)]

          #          [String]

          #          $StartupKeyPath,



          [Parameter(Mandatory = $false, ParameterSetName="TpmAndPinAndStartupKeyProtector", Position = 2)]

          [Parameter(Mandatory = $false, ParameterSetName="TpmAndPinProtector", Position = 1)]

          [Alias("p")]

          [System.Security.SecureString]

          $Pin,





          # 

          # TPM And Pin Protector 

          #



          [Parameter(Mandatory = $true, ParameterSetName="TpmAndPinProtector")]

          [Alias("tpp")]

          [System.Management.Automation.SwitchParameter]

          $TpmAndPinProtector = $false,



          # Defined in TPM And Pin And Startup Key Protector section above

          #          [Parameter(Mandatory = $false, ParameterSetName="TpmAndPinProtector", Position = 1)]

          #          [System.Security.SecureString]

          #          $Pin,





          # 

          # TPM And StartupKey Protector 

          #



          [Parameter(Mandatory = $true, ParameterSetName="TpmAndStartupKeyProtector")]

          [Alias("tskp")]

          [System.Management.Automation.SwitchParameter]

          $TpmAndStartupKeyProtector = $false,



          # Defined in the StartupKeyProtector section above

          #          [Parameter(Mandatory = $true, ParameterSetName="TpmAndStartupKeyProtector", Position = 1)]

          #          [String]

          #          $StartupKeyPath,



          # 

          # TPM Protector 

          #



          [Parameter(Mandatory = $true, ParameterSetName="TpmProtector")]

          [Alias("tpmp")]

          [System.Management.Automation.SwitchParameter]

          $TpmProtector = $false,



          # 

          # Recovery Key Protector 

          #



          [Parameter(Mandatory = $true, ParameterSetName="RecoveryKeyProtector")]

          [Alias("rkp")]

          [System.Management.Automation.SwitchParameter]

          $RecoveryKeyProtector = $false,



          [Parameter(Mandatory = $true, ParameterSetName="RecoveryKeyProtector", Position = 1)]

          [Alias("rk")]

          [String]

          $RecoveryKeyPath)



    process

    {



        Write-Debug "Begin Enable-BitLocker"



        #########

        # ValidMountPoint is a subset of the elements of MountPoint array.

        # If MountPoint array contains an element that is not a valid mount point then

        # the mount point is not part of ValidMountPoint

        # Only those BitLockerVolume structures are returned that are part of ValidMountPoint

        #

        # If "-whatif" is used then ValidMountPoint is always $null

        #########

        [string[]]$ValidMountPoint = $null





        if ($HardwareEncryption -eq $true -and $UsedSpaceOnly -eq $true)

        {

            $UsedSpaceOnly = $false

            Write-Warning $stringTable.WarningUsedSpaceOnlyAndHardwareEncryption

        }



        for($i=0; $i -lt $MountPoint.Count; $i++)

        {

            $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

            if ($BitLockerVolumeInternal -eq $null)

            {

                Write-Debug ("The following operation failed: Get-BitLockerVolumeInternal -MountPoint " + $MountPoint[$i])

                continue

            }



            Write-Debug ("MountPoint: " + $BitLockerVolumeInternal.MountPoint)



            $IsFullyDecrypted = $BitLockerVolumeInternal.VolumeStatus -eq [Microsoft.BitLocker.Structures.BitLockerVolumeStatus]::FullyDecrypted

            $IsOsVolume       = $BitLockerVolumeInternal.VolumeType -eq [Microsoft.BitLocker.Structures.BitLockerVolumeType]::OperatingSystem



            if ($pscmdlet.ShouldProcess($BitLockerVolumeInternal.MountPoint))

            {

                if ($IsFullyDecrypted -eq $true)

                {

                    $IsSystemEntropyReady = Test-SystemEntropyForBitLockerInternal

                    if ($IsSystemEntropyReady -eq $false)

                    {

                        $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $TPM_E_DEACTIVATED

                        Write-Error -Exception $ExceptionForHr

                        continue

                    }



                    if ($HardwareEncryption -eq $true)

                    {

                        $BitLockerVolumeInternal = Set-BitLockerVolumeInternal -MountPoint $MountPoint[$i] -ForceEncryptionType $FVE_FORCE_ENCRYPTION_TYPE_HARDWARE -UsedSpaceOnly $false

                    }

                    else

                    {

                        $BitLockerVolumeInternal = Set-BitLockerVolumeInternal -MountPoint $MountPoint[$i] -ForceEncryptionType $FVE_FORCE_ENCRYPTION_TYPE_UNSPECIFIED -UsedSpaceOnly $UsedSpaceOnly

                    }



                    Write-Debug "Set-BitLockerVolumeInternal returned $BitLockerVolumeInternal"

                    if ($BitLockerVolumeInternal -eq $null)

                    {

                        continue

                    }



                    if ($IsOsVolume -eq $true)

                    {

                        $IsTpmReady = Test-TpmForBitLockerInternal



                        if ($IsTpmReady -eq $true)

                        {

                            $IsTpmProtectorNeeded = Test-TpmProtectorNeededInternal -MountPoint $MountPoint[$i] -ParameterSetNameFromEnableBitLocker $PsCmdlet.ParameterSetName



                            if ($IsTpmProtectorNeeded -eq $true)

                            {

                                $BitLockerVolumeInternal = Add-BitLockerKeyProtector -TpmProtector -MountPoint $BitLockerVolumeInternal

                                Write-Debug "Add-BitLockerKeyProtector returned $BitLockerVolumeInternal"

                                if ($BitLockerVolumeInternal -eq $null)

                                {

                                    continue

                                }

                            }

                        }

                        else

                        {

                            $DoesPasswordProtectorExist     = $BitLockerVolumeInternal.KeyProtector | where-object {$_.KeyProtectorType -eq [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::Password}

                            $DoesExternalKeyProtectorExist  = $BitLockerVolumeInternal.KeyProtector | where-object {$_.KeyProtectorType -eq [Microsoft.BitLocker.Structures.BitLockerVolumeKeyProtectorType]::ExternalKey}



                            if ($DoesPasswordProtectorExist -eq $null               -and

                                $DoesExternalKeyProtectorExist -eq $null            -and

                                $PsCmdlet.ParameterSetName -ne "PasswordProtector"  -and

                                $PsCmdlet.ParameterSetName -ne "StartupKeyProtector")

                            {

                                $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $E_FAIL

                                Write-Error -Exception $ExceptionForHr -Message $stringTable.ErrorExternalKeyOrPasswordRequired

                                continue

                            }

                        }



                        if ($PsCmdlet.ParameterSetName -eq "AdAccountOrGroupProtector")

                        {                        

                            $RecoveryKeyProtectorCount = Get-RecoveryKeyProtectorsCountInternal -MountPoint $MountPoint[$i]

                            $IsTpmAvailable = Test-TpmForBitLockerInternal

                            if ( ($RecoveryKeyProtectorCount -lt $MINIMUM_REQUIRED_RECOVERY_PROTECTORS_WITH_TPM -and $IsTpmAvailable -eq $true) -or ($RecoveryKeyProtectorCount -lt $MINIMUM_REQUIRED_RECOVERY_PROTECTORS_WITHOUT_TPM -and $IsTpmAvailable -eq $false))

                            {

                                $ExceptionForHr = Get-ExceptionForHrInternal -HrUInt32 $E_FAIL

                                Write-Error -Exception $ExceptionForHr -Message $stringTable.ErrorSidProtectorRequiresAdditionalRecoveryProtector

                                continue

                            }

                        }

                    } # end if OS Volume

                } #end if VolumeStatus -eq FullyDecrypted





                if ($PsCmdlet.ParameterSetName -eq "PasswordProtector")

                {

                    $BitLockerVolumeInternal = Add-BitLockerKeyProtector -MountPoint $MountPoint[$i] -PasswordProtector -Password $Password

                }

                elseif ($PsCmdlet.ParameterSetName -eq "RecoveryPasswordProtector")

                {

                    #

                    # We call the internal add protector method because we

                    # don't want it to output the recovery password. This cmdlet will do it.

                    #



                    $nResult = 0



                    if ([string]::IsNullOrEmpty($RecoveryPassword))

                    {

                        $nResult = Add-RecoveryPasswordProtectorInternal $MountPoint[$i] -SuppressWarningMessage

                    }

                    else

                    {

                        $nResult = Add-RecoveryPasswordProtectorInternal $MountPoint[$i] $RecoveryPassword -SuppressWarningMessage

                    }



                    if ($nResult -eq 0)

                    {

                         $BitLockerVolumeInternal = Get-BitLockerVolumeInternal -MountPoint $MountPoint[$i]

                    }

                }

                elseif ($PsCmdlet.ParameterSetName -eq "StartupKeyProtector")

                {

                    $BitLockerVolumeInternal = Add-BitLockerKeyProtector -MountPoint $MountPoint[$i] -StartupKeyProtector -StartupKeyPath $StartupKeyPath

                }

                elseif ($PsCmdlet.ParameterSetName -eq "AdAccountOrGroupProtector")

                {

                    if ($Service -eq $false)

                    {

                        $BitLockerVolumeInternal = Add-BitLockerKeyProtector -MountPoint $MountPoint[$i] -AdAccountOrGroupProtector -AdAccountOrGroup $AdAccountOrGroup

                    }

                    else

                    {

                        $BitLockerVolumeInternal = Add-BitLockerKeyProtector -MountPoint $MountPoint[$i] -AdAccountOrGroupProtector -AdAccountOrGroup $AdAccountOrGroup -Service

                    }

                }

                elseif ($PsCmdlet.ParameterSetName -eq "TpmAndPinAndStartupKeyProtector")

                {

                    $BitLockerVolumeInternal = Add-BitLockerKeyProtector -MountPoint $MountPoint[$i] -TpmAndPinAndStartupKeyProtector -StartupKeyPath $StartupKeyPath -Pin $Pin

                }

                elseif ($PsCmdlet.ParameterSetName -eq "TpmAndPinProtector")

                {

                    $BitLockerVolumeInternal = Add-BitLockerKeyProtector -MountPoint $MountPoint[$i] -TpmAndPinProtector -Pin $Pin

                }

                elseif ($PsCmdlet.ParameterSetName -eq "TpmAndStartupKeyProtector")

                {

                    $BitLockerVolumeInternal = Add-BitLockerKeyProtector -MountPoint $MountPoint[$i] -TpmAndStartupKeyProtector -StartupKeyPath $StartupKeyPath

                }

                elseif ($PsCmdlet.ParameterSetName -eq "TpmProtector")

                {

                    $BitLockerVolumeInternal = Add-BitLockerKeyProtector -MountPoint $MountPoint[$i] -TpmProtector

                }

                elseif ($PsCmdlet.ParameterSetName -eq "RecoveryKeyProtector")

                {

                    $BitLockerVolumeInternal = Add-BitLockerKeyProtector -MountPoint $MountPoint[$i] -RecoveryKeyProtector -RecoveryKeyPath $RecoveryKeyPath

                }



                if ($BitLockerVolumeInternal -eq $null)

                {

                    Write-Debug ("Add-BitLockerKeyProtector did not return a bitlocker volume. ParameterSet: " + $PSCmdlet.ParameterSetName)

                    continue

                }





                if ($BitLockerVolumeInternal.VolumeType -eq [Microsoft.BitLocker.Structures.BitLockerVolumeType]::Data -or

                    $IsFullyDecrypted -ne $true)

                {

                    $NeedHardwareTest = $false

                }

                else

                {

                    $NeedHardwareTest = !$SkipHardwareTest

                }



                if ($EncryptionMethod -ne $null)

                {

                    $BitLockerVolumeInternal = Enable-BitLockerInternal -MountPoint $BitLockerVolumeInternal -EncryptionMethod $EncryptionMethod -SkipHardwareTest (!$NeedHardwareTest) -UsedSpaceOnly $UsedSpaceOnly

                }

                else

                {

                    $BitLockerVolumeInternal = Enable-BitLockerInternal -MountPoint $BitLockerVolumeInternal -SkipHardwareTest (!$NeedHardwareTest) -UsedSpaceOnly $UsedSpaceOnly

                }

                Write-Debug "Enable-BitLockerInternal returned $BitLockerVolumeInternal. EncryptionMethod: $EncryptionMethod   NeedHardwareTest: $NeedHardwareTest    UsedSpaceOnly: $UsedSpaceOnly"





                if ($BitLockerVolumeInternal -eq $null)

                {

                    Write-Debug ("Could not enable bitlocker on " + $MountPoint[$i])

                    continue

                }





                Show-BitLockerRequiredActionsInternal -MountPoint $BitLockerVolumeInternal -SkipHardwareTest (!$NeedHardwareTest)



                $ValidMountPoint = $ValidMountPoint + $MountPoint[$i]



            } #end ShouldProcess

        } #end for each MountPoint





        Write-Debug "ValidMountPoint: $ValidMountPoint"



        if ($ValidMountPoint)

        {

            $BitLockerVolume = Get-BitLockerVolume -MountPoint $ValidMountPoint



            $BitLockerVolume

        }

        else

        {

            Write-Debug "No valid mount point was provided that can have bitlocker enabled"

        }





        Write-Debug "End Enable-BitLocker $BitLockerVolume"



    } #end process record

}


Youez - 2016 - github.com/yon3zu
LinuXploit